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