BAEL-6791 - Added in existing module Unit tests and Bench mark tests. (#14744)

* BAEL-6791 - Added in existing module Unit tests and Bench mark tests.

* BAEL-6791 - Put all of your code in a single package that refers to your article

* BAEL-6791 -
PR - add a newline after the package statements
PR - use 2-space indents for line continuations.
Use given-when-then naming convention for test methods
This commit is contained in:
Amol Gote 2023-09-14 22:00:04 -04:00 committed by GitHub
parent c1b2a9d4f7
commit 78b183b581
3 changed files with 198 additions and 0 deletions

View File

@ -0,0 +1,73 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
@Threads(10) // 10 threads for the test
public class BenchMarkRunner {
private Hashtable<String, Integer> hashTable;
private ConcurrentHashMap<String, Integer> concurrentHashMap;
@Setup(Level.Trial)
public void setup() {
hashTable = new Hashtable<>();
concurrentHashMap = new ConcurrentHashMap<>();
}
@Benchmark
@Group("hashtable")
public void benchmarkHashtablePut() {
for (int i = 0; i < 10000; i++) {
hashTable.put(String.valueOf(i), i);
}
}
@Benchmark
@Group("hashtable")
public void benchmarkHashtableGet(Blackhole blackhole) {
for (int i = 0; i < 10000; i++) {
Integer value = hashTable.get(String.valueOf(i));
blackhole.consume(value);
}
}
@Benchmark
@Group("concurrentHashMap")
public void benchmarkConcurrentHashMapPut() {
for (int i = 0; i < 10000; i++) {
concurrentHashMap.put(String.valueOf(i), i);
}
}
@Benchmark
@Group("concurrentHashMap")
public void benchmarkConcurrentHashMapGet(Blackhole blackhole) {
for (int i = 0; i < 10000; i++) {
Integer value = concurrentHashMap.get(String.valueOf(i));
blackhole.consume(value);
}
}
public static void main(String[] args) throws Exception {
Options options = new OptionsBuilder()
.include(BenchMarkRunner.class.getSimpleName())
.shouldFailOnError(true)
.shouldDoGC(true)
.jvmArgs("-server")
.build();
new Runner(options).run();
}
}

View File

@ -0,0 +1,62 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.junit.Test;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class ConcurrentHashMapUnitTest {
@Test
public void givenEmptyConcurrentHashMap_whenValuesAreAdded_thenValuesCanBeRetrieved() {
ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Key1", "1");
concurrentHashMap.put("Key2", "2");
concurrentHashMap.putIfAbsent("Key3", "3");
String value = concurrentHashMap.get("Key2");
assertEquals("1", concurrentHashMap.get("Key1"));
assertEquals("2", value);
assertEquals("3", concurrentHashMap.get("Key3"));
}
@Test
public void givenPopulatedConcurrentHashMap_whenModifiedDuringIteration_thenShouldNotThrowConcurrentModificationException() throws InterruptedException {
ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Key1", 1);
concurrentHashMap.put("Key2", 2);
concurrentHashMap.put("Key3", 3);
AtomicBoolean exceptionCaught = new AtomicBoolean(false);
Thread iteratorThread = new Thread(() -> {
Iterator<String> it = concurrentHashMap.keySet().iterator();
try {
while (it.hasNext()) {
it.next();
Thread.sleep(100);
}
} catch (ConcurrentModificationException e) {
exceptionCaught.set(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread modifierThread = new Thread(() -> {
try {
Thread.sleep(50);
concurrentHashMap.put("Key4", 4);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
iteratorThread.start();
modifierThread.start();
iteratorThread.join();
modifierThread.join();
assertFalse(exceptionCaught.get());
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.junit.Test;
import java.util.ConcurrentModificationException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class HashtableUnitTest {
@Test
public void givenEmptyHashtable_whenValuesAreAdded_thenValuesCanBeRetrieved() {
Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put("Key1", "1");
hashtable.put("Key2", "2");
hashtable.putIfAbsent("Key3", "3");
String value = hashtable.get("Key2");
assertEquals("1", hashtable.get("Key1"));
assertEquals("2", value);
assertEquals("3", hashtable.get("Key3"));
}
@Test
public void givenPopulatedHashtable_whenModifiedDuringIteration_thenShouldThrowConcurrentModificationException() throws InterruptedException {
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("Key1", 1);
hashtable.put("Key2", 2);
hashtable.put("Key3", 3);
AtomicBoolean exceptionCaught = new AtomicBoolean(false);
Thread iteratorThread = new Thread(() -> {
Iterator<String> it = hashtable.keySet().iterator();
try {
while (it.hasNext()) {
it.next();
Thread.sleep(100);
}
} catch (ConcurrentModificationException e) {
exceptionCaught.set(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread modifierThread = new Thread(() -> {
try {
Thread.sleep(50);
hashtable.put("Key4", 4);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
iteratorThread.start();
modifierThread.start();
iteratorThread.join();
modifierThread.join();
assertTrue(exceptionCaught.get());
}
}