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:
parent
c1b2a9d4f7
commit
78b183b581
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue