From 2106623d9dc4e113b1d5ec5104b0b84301fb0d5c Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 23 Nov 2020 09:56:16 +0530 Subject: [PATCH 1/8] Added changes to fix the details --- ...oncurrentHashMapVsSynchronizedMapTest.java | 159 ++++++++++++++++++ .../ConcurrentModificationErrorTest.java | 41 +++++ .../cuncurrenthashmap/PerformanceTest.java | 54 ++++++ .../map/cuncurrenthashmap/UserId.java | 17 ++ 4 files changed, 271 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java new file mode 100644 index 0000000000..6a7716d38a --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java @@ -0,0 +1,159 @@ +package com.baeldung.map.cuncurrenthashmap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; + +public class ConcurrentHashMapVsSynchronizedMapTest { + + public final static int THREAD_POOL_SIZE = 5; + public final static int TEST_ITERATIONS = 5; + public final static int TEST_NO_ITEMS = 500000; + + @Test + public void randomReadAndWritePerformaceTest_cuncurrentHashMap_faster() + throws InterruptedException { + // For synchronizedMap + Long totalTimeForSynchronizedMap = 0l; + Map slowerMap = Collections + .synchronizedMap(new HashMap()); + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForSynchronizedMap += performReadAndWriteTest(slowerMap); + } + Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; + + // For ConcurrentHashMap Object + Long totalTimeForCuncurrentHashMap = 0l; + Map fasterMap = new ConcurrentHashMap<>(); + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForCuncurrentHashMap += performReadAndWriteTest(fasterMap); + } + Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + } + + @Test + public void randomWritePerformaceTest_cuncurrentHashMap_faster() throws InterruptedException { + // For synchronizedMap + Long totalTimeForSynchronizedMap = 0l; + Map slowerMap = Collections + .synchronizedMap(new HashMap()); + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForSynchronizedMap += performWriteTest(slowerMap); + } + Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; + + // For ConcurrentHashMap Object + Long totalTimeForCuncurrentHashMap = 0l; + Map fasterMap = new ConcurrentHashMap<>(); + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForCuncurrentHashMap += performWriteTest(fasterMap); + } + Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + } + + @Test + public void randomReadPerformaceTest_cuncurrentHashMap_faster() throws InterruptedException { + + Map slowerMap = Collections + .synchronizedMap(addItems(new HashMap())); + // For synchronizedMap + Long totalTimeForSynchronizedMap = 0l; + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForSynchronizedMap += performReadTest(slowerMap); + } + Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; + + Map fasterMap = Collections + .synchronizedMap(addItems(new ConcurrentHashMap())); + // For ConcurrentHashMap Object + Long totalTimeForCuncurrentHashMap = 0l; + new ConcurrentHashMap<>(); + for (int i = 0; i < TEST_ITERATIONS; i++) { + totalTimeForCuncurrentHashMap += performReadTest(fasterMap); + } + Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + } + + private Map addItems(Map map) { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.put(String.valueOf(randNumber), randNumber); + } + return map; + } + + private long performWriteTest(final Map map) throws InterruptedException { + long startTime = System.nanoTime(); + ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + for (int j = 0; j < THREAD_POOL_SIZE; j++) { + exectures.execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.put(String.valueOf(randNumber), randNumber); + } + } + }); + } + exectures.shutdown(); + exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + long entTime = System.nanoTime(); + return (entTime - startTime) / 1000000L; + } + + private long performReadAndWriteTest(final Map map) + throws InterruptedException { + long startTime = System.nanoTime(); + ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + for (int j = 0; j < THREAD_POOL_SIZE; j++) { + exectures.execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + Integer value = map.get(String.valueOf(randNumber)); + map.put(String.valueOf(randNumber), randNumber); + } + } + }); + } + exectures.shutdown(); + exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + long entTime = System.nanoTime(); + return (entTime - startTime) / 1000000L; + } + + private long performReadTest(final Map map) throws InterruptedException { + long startTime = System.nanoTime(); + ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + for (int j = 0; j < THREAD_POOL_SIZE; j++) { + exectures.execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + Integer value = map.get(String.valueOf(randNumber)); + } + } + }); + } + exectures.shutdown(); + exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + long entTime = System.nanoTime(); + return (entTime - startTime) / 1000000L; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java new file mode 100644 index 0000000000..993354d6d0 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java @@ -0,0 +1,41 @@ +package com.baeldung.map.cuncurrenthashmap; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Assert; +import org.junit.Test; + +public class ConcurrentModificationErrorTest { + + @Test(expected = ConcurrentModificationException.class) + public void whenRemoveAndAddOnHashMap_thenCuncurrentModificationError() { + Map map = new HashMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Map synchronizedMap = Collections.synchronizedMap(map); + Iterator> iterator = synchronizedMap.entrySet().iterator(); + while (iterator.hasNext()) { + synchronizedMap.put(4, "Modification"); + iterator.next(); + } + } + + public void whenRemoveAndAddOnCuncurrentHashMap_thenNoError() { + Map map = new ConcurrentHashMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Iterator> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + map.put(4, "Modification"); + iterator.next(); + } + + Assert.assertEquals(4, map.size()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java new file mode 100644 index 0000000000..9751decf53 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java @@ -0,0 +1,54 @@ +package com.baeldung.map.cuncurrenthashmap; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Test; + +public class PerformanceTest { + + @Test(expected = ConcurrentModificationException.class) + public void whenRemoveAndAddOnHashMap_thenCuncurrentModificationError() { + Map map = new HashMap<>(); + Map synchronizedMap = Collections.synchronizedMap(map); + long startTime = System.currentTimeMillis(); + for(int i=0; i<100000; i++) { + UserId userId = new UserId(1); + synchronizedMap.put(userId, userId.toString()); + } + long endTime = System.currentTimeMillis(); + long addTimeForSynchronized = endTime-startTime; + + startTime = System.currentTimeMillis(); + for(int i=0; i<100000; i++) { + UserId userId = new UserId(1); + synchronizedMap.get(userId); + } + endTime = System.currentTimeMillis(); + long fetchTimeForSynchronized = endTime-startTime; + + Map map1 = new ConcurrentHashMap<>(); + startTime = System.currentTimeMillis(); + for(int i=0; i<100000; i++) { + UserId userId = new UserId(1); + map1.put(userId, userId.toString()); + } + endTime = System.currentTimeMillis(); + long addTimeForConcurrent = endTime-startTime; + + startTime = System.currentTimeMillis(); + for(int i=0; i<100000; i++) { + UserId userId = new UserId(1); + map1.get(userId); + } + endTime = System.currentTimeMillis(); + long fetchTimeForConcurrent = endTime-startTime; + + System.out.println("ABC"); + + } + +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java new file mode 100644 index 0000000000..a69976180d --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java @@ -0,0 +1,17 @@ +package com.baeldung.map.cuncurrenthashmap; + +public class UserId { + + private int id; + + public UserId(int id) { + super(); + this.id = id; + } + + @Override + public int hashCode() { + return this.id%10; + } + +} From 6238c637c737c6acaf55493cd1a7a31e5dd796d7 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 23 Nov 2020 14:54:44 +0530 Subject: [PATCH 2/8] BAEL-4686: Performance test --- ...hMapVsSynchronizedMapPerformanceTest.java} | 41 +++++++------- .../ConcurrentModificationErrorTest.java | 6 +-- .../cuncurrenthashmap/PerformanceTest.java | 54 ------------------- .../map/cuncurrenthashmap/UserId.java | 17 ------ 4 files changed, 23 insertions(+), 95 deletions(-) rename core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/{cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java => concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java} (82%) rename core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/{cuncurrenthashmap => concurrenthashmap}/ConcurrentModificationErrorTest.java (87%) delete mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java delete mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java similarity index 82% rename from core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java rename to core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java index 6a7716d38a..eb0c58a8b0 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentHashMapVsSynchronizedMapTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java @@ -1,4 +1,4 @@ -package com.baeldung.map.cuncurrenthashmap; +package com.baeldung.map.concurrenthashmap; import java.util.Collections; import java.util.HashMap; @@ -11,14 +11,14 @@ import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -public class ConcurrentHashMapVsSynchronizedMapTest { +public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { public final static int THREAD_POOL_SIZE = 5; public final static int TEST_ITERATIONS = 5; public final static int TEST_NO_ITEMS = 500000; @Test - public void randomReadAndWritePerformaceTest_cuncurrentHashMap_faster() + public void randomReadAndWritePerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { // For synchronizedMap Long totalTimeForSynchronizedMap = 0l; @@ -30,18 +30,18 @@ public class ConcurrentHashMapVsSynchronizedMapTest { Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; // For ConcurrentHashMap Object - Long totalTimeForCuncurrentHashMap = 0l; + Long totalTimeForConcurrentHashMap = 0l; Map fasterMap = new ConcurrentHashMap<>(); for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForCuncurrentHashMap += performReadAndWriteTest(fasterMap); + totalTimeForConcurrentHashMap += performReadAndWriteTest(fasterMap); } - Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); } @Test - public void randomWritePerformaceTest_cuncurrentHashMap_faster() throws InterruptedException { + public void randomWritePerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { // For synchronizedMap Long totalTimeForSynchronizedMap = 0l; Map slowerMap = Collections @@ -52,18 +52,18 @@ public class ConcurrentHashMapVsSynchronizedMapTest { Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; // For ConcurrentHashMap Object - Long totalTimeForCuncurrentHashMap = 0l; + Long totalTimeForConcurrentHashMap = 0l; Map fasterMap = new ConcurrentHashMap<>(); for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForCuncurrentHashMap += performWriteTest(fasterMap); + totalTimeForConcurrentHashMap += performWriteTest(fasterMap); } - Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); } @Test - public void randomReadPerformaceTest_cuncurrentHashMap_faster() throws InterruptedException { + public void randomReadPerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { Map slowerMap = Collections .synchronizedMap(addItems(new HashMap())); @@ -74,17 +74,16 @@ public class ConcurrentHashMapVsSynchronizedMapTest { } Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; - Map fasterMap = Collections - .synchronizedMap(addItems(new ConcurrentHashMap())); + Map fasterMap = addItems(new ConcurrentHashMap()); // For ConcurrentHashMap Object - Long totalTimeForCuncurrentHashMap = 0l; + Long totalTimeForConcurrentHashMap = 0l; new ConcurrentHashMap<>(); for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForCuncurrentHashMap += performReadTest(fasterMap); + totalTimeForConcurrentHashMap += performReadTest(fasterMap); } - Long avgTimeForCuncurrentHashMap = totalTimeForCuncurrentHashMap / TEST_ITERATIONS; + Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForCuncurrentHashMap); + Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); } private Map addItems(Map map) { @@ -125,7 +124,7 @@ public class ConcurrentHashMapVsSynchronizedMapTest { public void run() { for (int i = 0; i < TEST_NO_ITEMS; i++) { Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - Integer value = map.get(String.valueOf(randNumber)); + map.get(String.valueOf(randNumber)); map.put(String.valueOf(randNumber), randNumber); } } @@ -146,7 +145,7 @@ public class ConcurrentHashMapVsSynchronizedMapTest { public void run() { for (int i = 0; i < TEST_NO_ITEMS; i++) { Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - Integer value = map.get(String.valueOf(randNumber)); + map.get(String.valueOf(randNumber)); } } }); diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java similarity index 87% rename from core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java rename to core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java index 993354d6d0..998496720e 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/ConcurrentModificationErrorTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java @@ -1,4 +1,4 @@ -package com.baeldung.map.cuncurrenthashmap; +package com.baeldung.map.concurrenthashmap; import java.util.Collections; import java.util.ConcurrentModificationException; @@ -14,7 +14,7 @@ import org.junit.Test; public class ConcurrentModificationErrorTest { @Test(expected = ConcurrentModificationException.class) - public void whenRemoveAndAddOnHashMap_thenCuncurrentModificationError() { + public void whenRemoveAndAddOnHashMap_thenConcurrentModificationError() { Map map = new HashMap<>(); map.put(1, "baeldung"); map.put(2, "HashMap"); @@ -26,7 +26,7 @@ public class ConcurrentModificationErrorTest { } } - public void whenRemoveAndAddOnCuncurrentHashMap_thenNoError() { + public void whenRemoveAndAddOnConcurrentHashMap_thenNoError() { Map map = new ConcurrentHashMap<>(); map.put(1, "baeldung"); map.put(2, "HashMap"); diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java deleted file mode 100644 index 9751decf53..0000000000 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/PerformanceTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.map.cuncurrenthashmap; - -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.Test; - -public class PerformanceTest { - - @Test(expected = ConcurrentModificationException.class) - public void whenRemoveAndAddOnHashMap_thenCuncurrentModificationError() { - Map map = new HashMap<>(); - Map synchronizedMap = Collections.synchronizedMap(map); - long startTime = System.currentTimeMillis(); - for(int i=0; i<100000; i++) { - UserId userId = new UserId(1); - synchronizedMap.put(userId, userId.toString()); - } - long endTime = System.currentTimeMillis(); - long addTimeForSynchronized = endTime-startTime; - - startTime = System.currentTimeMillis(); - for(int i=0; i<100000; i++) { - UserId userId = new UserId(1); - synchronizedMap.get(userId); - } - endTime = System.currentTimeMillis(); - long fetchTimeForSynchronized = endTime-startTime; - - Map map1 = new ConcurrentHashMap<>(); - startTime = System.currentTimeMillis(); - for(int i=0; i<100000; i++) { - UserId userId = new UserId(1); - map1.put(userId, userId.toString()); - } - endTime = System.currentTimeMillis(); - long addTimeForConcurrent = endTime-startTime; - - startTime = System.currentTimeMillis(); - for(int i=0; i<100000; i++) { - UserId userId = new UserId(1); - map1.get(userId); - } - endTime = System.currentTimeMillis(); - long fetchTimeForConcurrent = endTime-startTime; - - System.out.println("ABC"); - - } - -} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java deleted file mode 100644 index a69976180d..0000000000 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/cuncurrenthashmap/UserId.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.map.cuncurrenthashmap; - -public class UserId { - - private int id; - - public UserId(int id) { - super(); - this.id = id; - } - - @Override - public int hashCode() { - return this.id%10; - } - -} From 74eb0bd0e9841e507846db2251dbb8d6b79fb438 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 23 Nov 2020 17:32:18 +0530 Subject: [PATCH 3/8] BAEL-4686: Corrected the test --- ...shMapVsSynchronizedMapPerformanceTest.java | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java index eb0c58a8b0..573087d5a5 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java @@ -15,7 +15,7 @@ public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { public final static int THREAD_POOL_SIZE = 5; public final static int TEST_ITERATIONS = 5; - public final static int TEST_NO_ITEMS = 500000; + public final static int TEST_NO_ITEMS = 10000; @Test public void randomReadAndWritePerformaceTest_ConcurrentHashMap_faster() @@ -40,6 +40,28 @@ public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); } + private long performReadAndWriteTest(final Map map) + throws InterruptedException { + long startTime = System.nanoTime(); + ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + for (int j = 0; j < THREAD_POOL_SIZE; j++) { + exectures.execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.get(String.valueOf(randNumber)); + map.put(String.valueOf(randNumber), randNumber); + } + } + }); + } + exectures.shutdown(); + exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + long entTime = System.nanoTime(); + return (entTime - startTime) / 1000000L; + } + @Test public void randomWritePerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { // For synchronizedMap @@ -62,6 +84,26 @@ public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); } + private long performWriteTest(final Map map) throws InterruptedException { + long startTime = System.nanoTime(); + ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + for (int j = 0; j < THREAD_POOL_SIZE; j++) { + exectures.execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.put(String.valueOf(randNumber), randNumber); + } + } + }); + } + exectures.shutdown(); + exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + long entTime = System.nanoTime(); + return (entTime - startTime) / 1000000L; + } + @Test public void randomReadPerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { @@ -94,48 +136,6 @@ public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { return map; } - private long performWriteTest(final Map map) throws InterruptedException { - long startTime = System.nanoTime(); - ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); - for (int j = 0; j < THREAD_POOL_SIZE; j++) { - exectures.execute(new Runnable() { - @Override - public void run() { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.put(String.valueOf(randNumber), randNumber); - } - } - }); - } - exectures.shutdown(); - exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - long entTime = System.nanoTime(); - return (entTime - startTime) / 1000000L; - } - - private long performReadAndWriteTest(final Map map) - throws InterruptedException { - long startTime = System.nanoTime(); - ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); - for (int j = 0; j < THREAD_POOL_SIZE; j++) { - exectures.execute(new Runnable() { - @Override - public void run() { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.get(String.valueOf(randNumber)); - map.put(String.valueOf(randNumber), randNumber); - } - } - }); - } - exectures.shutdown(); - exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - long entTime = System.nanoTime(); - return (entTime - startTime) / 1000000L; - } - private long performReadTest(final Map map) throws InterruptedException { long startTime = System.nanoTime(); ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); From 4f252b72e3b2d1a8b7a756fc2bbcdc1e8655b920 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 23 Nov 2020 20:10:17 +0530 Subject: [PATCH 4/8] BAEL-4686:Allow Null test --- .../concurrenthashmap/NullAllowInMapTest.java | 27 +++++++++++++++++++ ...formanceTest.java => PerformanceTest.java} | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java rename core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/{ConcurrentHashMapVsSynchronizedMapPerformanceTest.java => PerformanceTest.java} (99%) diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java new file mode 100644 index 0000000000..23c76e59e8 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java @@ -0,0 +1,27 @@ +package com.baeldung.map.concurrenthashmap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Assert; +import org.junit.Test; + +public class NullAllowInMapTest { + + @Test + public void allowOnlyNull_In_SynchronizedMap() { + Map map = Collections + .synchronizedMap(new HashMap()); + map.put(null, 1); + Assert.assertTrue(map.get(null).equals(1)); + } + + @Test(expected = NullPointerException.class) + public void allowOnlyNull_In_ConcurrentHasMap() { + Map map = new ConcurrentHashMap<>(); + map.put(null, 1); + } + +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java similarity index 99% rename from core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java rename to core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java index 573087d5a5..5321d33b36 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentHashMapVsSynchronizedMapPerformanceTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java @@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -public class ConcurrentHashMapVsSynchronizedMapPerformanceTest { +public class PerformanceTest { public final static int THREAD_POOL_SIZE = 5; public final static int TEST_ITERATIONS = 5; From fa6b90da6f0e8cedf87b6536769de7256316fbcc Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 30 Nov 2020 07:12:58 +0530 Subject: [PATCH 5/8] BAEL-4686: Review comments implemented --- .../core-java-collections-maps-3/pom.xml | 6 +- .../MapPerformanceComparison.java | 96 +++++++++++ .../ConcurrentModificationErrorTest.java | 41 ----- .../concurrenthashmap/NullAllowInMapTest.java | 27 --- .../concurrenthashmap/PerformanceTest.java | 158 ------------------ 5 files changed, 101 insertions(+), 227 deletions(-) create mode 100644 core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/concurrenthashmap/MapPerformanceComparison.java delete mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java delete mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java delete mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java diff --git a/core-java-modules/core-java-collections-maps-3/pom.xml b/core-java-modules/core-java-collections-maps-3/pom.xml index f547968b22..577ad58255 100644 --- a/core-java-modules/core-java-collections-maps-3/pom.xml +++ b/core-java-modules/core-java-collections-maps-3/pom.xml @@ -15,7 +15,11 @@ - + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + diff --git a/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/concurrenthashmap/MapPerformanceComparison.java b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/concurrenthashmap/MapPerformanceComparison.java new file mode 100644 index 0000000000..c788dbc27d --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/concurrenthashmap/MapPerformanceComparison.java @@ -0,0 +1,96 @@ +package com.baeldung.map.concurrenthashmap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +@Fork(5) +@Threads(10) +@Warmup(iterations = 5) +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class MapPerformanceComparison { + + private int TEST_NO_ITEMS; + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + + @Setup + public void setup() { + TEST_NO_ITEMS = 1000; + } + + @Benchmark + public void randomReadAndWriteSynchronizedMap() { + Map map = Collections.synchronizedMap(new HashMap()); + performReadAndWriteTest(map); + } + + @Benchmark + public void randomReadAndWriteConcurrentHashMap() { + Map map = new ConcurrentHashMap<>(); + performReadAndWriteTest(map); + } + + private void performReadAndWriteTest(final Map map) { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.get(String.valueOf(randNumber)); + map.put(String.valueOf(randNumber), randNumber); + } + } + + @Benchmark + public void randomWriteSynchronizedMap() { + Map map = Collections.synchronizedMap(new HashMap()); + performWriteTest(map); + } + + @Benchmark + public void randomWriteConcurrentHashMap() { + Map map = new ConcurrentHashMap<>(); + performWriteTest(map); + } + + private void performWriteTest(final Map map) { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.put(String.valueOf(randNumber), randNumber); + } + } + + @Benchmark + public void randomReadSynchronizedMap() { + Map map = Collections.synchronizedMap(new HashMap()); + performReadTest(map); + } + + @Benchmark + public void randomReadConcurrentHashMap() { + Map map = new ConcurrentHashMap<>(); + performReadTest(map); + } + + private void performReadTest(final Map map) { + for (int i = 0; i < TEST_NO_ITEMS; i++) { + Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); + map.get(String.valueOf(randNumber)); + } + } +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java deleted file mode 100644 index 998496720e..0000000000 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.map.concurrenthashmap; - -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.Assert; -import org.junit.Test; - -public class ConcurrentModificationErrorTest { - - @Test(expected = ConcurrentModificationException.class) - public void whenRemoveAndAddOnHashMap_thenConcurrentModificationError() { - Map map = new HashMap<>(); - map.put(1, "baeldung"); - map.put(2, "HashMap"); - Map synchronizedMap = Collections.synchronizedMap(map); - Iterator> iterator = synchronizedMap.entrySet().iterator(); - while (iterator.hasNext()) { - synchronizedMap.put(4, "Modification"); - iterator.next(); - } - } - - public void whenRemoveAndAddOnConcurrentHashMap_thenNoError() { - Map map = new ConcurrentHashMap<>(); - map.put(1, "baeldung"); - map.put(2, "HashMap"); - Iterator> iterator = map.entrySet().iterator(); - while (iterator.hasNext()) { - map.put(4, "Modification"); - iterator.next(); - } - - Assert.assertEquals(4, map.size()); - } -} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java deleted file mode 100644 index 23c76e59e8..0000000000 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.map.concurrenthashmap; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.Assert; -import org.junit.Test; - -public class NullAllowInMapTest { - - @Test - public void allowOnlyNull_In_SynchronizedMap() { - Map map = Collections - .synchronizedMap(new HashMap()); - map.put(null, 1); - Assert.assertTrue(map.get(null).equals(1)); - } - - @Test(expected = NullPointerException.class) - public void allowOnlyNull_In_ConcurrentHasMap() { - Map map = new ConcurrentHashMap<>(); - map.put(null, 1); - } - -} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java deleted file mode 100644 index 5321d33b36..0000000000 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/PerformanceTest.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.baeldung.map.concurrenthashmap; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.junit.Assert; -import org.junit.Test; - -public class PerformanceTest { - - public final static int THREAD_POOL_SIZE = 5; - public final static int TEST_ITERATIONS = 5; - public final static int TEST_NO_ITEMS = 10000; - - @Test - public void randomReadAndWritePerformaceTest_ConcurrentHashMap_faster() - throws InterruptedException { - // For synchronizedMap - Long totalTimeForSynchronizedMap = 0l; - Map slowerMap = Collections - .synchronizedMap(new HashMap()); - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForSynchronizedMap += performReadAndWriteTest(slowerMap); - } - Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; - - // For ConcurrentHashMap Object - Long totalTimeForConcurrentHashMap = 0l; - Map fasterMap = new ConcurrentHashMap<>(); - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForConcurrentHashMap += performReadAndWriteTest(fasterMap); - } - Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); - } - - private long performReadAndWriteTest(final Map map) - throws InterruptedException { - long startTime = System.nanoTime(); - ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); - for (int j = 0; j < THREAD_POOL_SIZE; j++) { - exectures.execute(new Runnable() { - @Override - public void run() { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.get(String.valueOf(randNumber)); - map.put(String.valueOf(randNumber), randNumber); - } - } - }); - } - exectures.shutdown(); - exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - long entTime = System.nanoTime(); - return (entTime - startTime) / 1000000L; - } - - @Test - public void randomWritePerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { - // For synchronizedMap - Long totalTimeForSynchronizedMap = 0l; - Map slowerMap = Collections - .synchronizedMap(new HashMap()); - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForSynchronizedMap += performWriteTest(slowerMap); - } - Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; - - // For ConcurrentHashMap Object - Long totalTimeForConcurrentHashMap = 0l; - Map fasterMap = new ConcurrentHashMap<>(); - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForConcurrentHashMap += performWriteTest(fasterMap); - } - Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); - } - - private long performWriteTest(final Map map) throws InterruptedException { - long startTime = System.nanoTime(); - ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); - for (int j = 0; j < THREAD_POOL_SIZE; j++) { - exectures.execute(new Runnable() { - @Override - public void run() { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.put(String.valueOf(randNumber), randNumber); - } - } - }); - } - exectures.shutdown(); - exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - long entTime = System.nanoTime(); - return (entTime - startTime) / 1000000L; - } - - @Test - public void randomReadPerformaceTest_ConcurrentHashMap_faster() throws InterruptedException { - - Map slowerMap = Collections - .synchronizedMap(addItems(new HashMap())); - // For synchronizedMap - Long totalTimeForSynchronizedMap = 0l; - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForSynchronizedMap += performReadTest(slowerMap); - } - Long avgTimeForSynchronizedMap = totalTimeForSynchronizedMap / TEST_ITERATIONS; - - Map fasterMap = addItems(new ConcurrentHashMap()); - // For ConcurrentHashMap Object - Long totalTimeForConcurrentHashMap = 0l; - new ConcurrentHashMap<>(); - for (int i = 0; i < TEST_ITERATIONS; i++) { - totalTimeForConcurrentHashMap += performReadTest(fasterMap); - } - Long avgTimeForConcurrentHashMap = totalTimeForConcurrentHashMap / TEST_ITERATIONS; - - Assert.assertTrue(avgTimeForSynchronizedMap > avgTimeForConcurrentHashMap); - } - - private Map addItems(Map map) { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.put(String.valueOf(randNumber), randNumber); - } - return map; - } - - private long performReadTest(final Map map) throws InterruptedException { - long startTime = System.nanoTime(); - ExecutorService exectures = Executors.newFixedThreadPool(THREAD_POOL_SIZE); - for (int j = 0; j < THREAD_POOL_SIZE; j++) { - exectures.execute(new Runnable() { - @Override - public void run() { - for (int i = 0; i < TEST_NO_ITEMS; i++) { - Integer randNumber = (int) Math.ceil(Math.random() * TEST_NO_ITEMS); - map.get(String.valueOf(randNumber)); - } - } - }); - } - exectures.shutdown(); - exectures.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - long entTime = System.nanoTime(); - return (entTime - startTime) / 1000000L; - } -} \ No newline at end of file From cd79c3f2c7c686b2c32485698e3d5fbcfdb3e3ae Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 30 Nov 2020 07:25:51 +0530 Subject: [PATCH 6/8] Added changes based on review comments --- .../ConcurrentModificationErrorUnitTest.java | 41 +++++++++++++++++++ .../NullAllowInMapUnitTest.java | 40 ++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java new file mode 100644 index 0000000000..899c902fb0 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.map.concurrenthashmap; + +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Assert; +import org.junit.Test; + +public class ConcurrentModificationErrorUnitTest { + + @Test(expected = ConcurrentModificationException.class) + public void whenRemoveAndAddOnHashMap_thenConcurrentModificationError() { + Map map = new HashMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Map synchronizedMap = Collections.synchronizedMap(map); + Iterator> iterator = synchronizedMap.entrySet().iterator(); + while (iterator.hasNext()) { + synchronizedMap.put(3, "Modification"); + iterator.next(); + } + } + + public void whenRemoveAndAddOnConcurrentHashMap_thenNoError() { + Map map = new ConcurrentHashMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Iterator> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + map.put(3, "Modification"); + iterator.next(); + } + + Assert.assertEquals(3, map.size()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java new file mode 100644 index 0000000000..60e293f4b3 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.map.concurrenthashmap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Assert; +import org.junit.Test; + +public class NullAllowInMapUnitTest { + + @Test + public void allowNullKey_In_SynchronizedMap() { + Map map = Collections + .synchronizedMap(new HashMap()); + map.put(null, 1); + Assert.assertTrue(map.get(null).equals(1)); + } + + @Test(expected = NullPointerException.class) + public void allowNullKey_In_ConcurrentHasMap() { + Map map = new ConcurrentHashMap<>(); + map.put(null, 1); + } + + @Test + public void allowNullValue_In_SynchronizedMap() { + Map map = Collections.synchronizedMap(new HashMap()); + map.put("1", null); + Assert.assertNull(map.get("1")); + } + + @Test(expected = NullPointerException.class) + public void allowNullValue_In_ConcurrentHasMap() { + Map map = new ConcurrentHashMap<>(); + map.put("1", null); + } + +} \ No newline at end of file From da0d850880040b202df70a703a9b3a8f68a8825b Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Wed, 9 Dec 2020 17:45:25 +0530 Subject: [PATCH 7/8] BAEL-4686: Added some more test cases for TreeMap and LinkedHashMap --- .../ConcurrentModificationErrorUnitTest.java | 29 +++++++++++++++ .../NullAllowInMapUnitTest.java | 37 ++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java index 899c902fb0..4264e613f2 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/ConcurrentModificationErrorUnitTest.java @@ -4,8 +4,10 @@ import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import org.junit.Assert; @@ -25,7 +27,34 @@ public class ConcurrentModificationErrorUnitTest { iterator.next(); } } + + @Test(expected = ConcurrentModificationException.class) + public void whenRemoveAndAddOnTreeMap_thenConcurrentModificationError() { + Map map = new TreeMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Map synchronizedMap = Collections.synchronizedMap(map); + Iterator> iterator = synchronizedMap.entrySet().iterator(); + while (iterator.hasNext()) { + synchronizedMap.put(3, "Modification"); + iterator.next(); + } + } + + @Test(expected = ConcurrentModificationException.class) + public void whenRemoveAndAddOnLinkedHashMap_thenConcurrentModificationError() { + Map map = new LinkedHashMap<>(); + map.put(1, "baeldung"); + map.put(2, "HashMap"); + Map synchronizedMap = Collections.synchronizedMap(map); + Iterator> iterator = synchronizedMap.entrySet().iterator(); + while (iterator.hasNext()) { + synchronizedMap.put(3, "Modification"); + iterator.next(); + } + } + @Test public void whenRemoveAndAddOnConcurrentHashMap_thenNoError() { Map map = new ConcurrentHashMap<>(); map.put(1, "baeldung"); diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java index 60e293f4b3..c5fc57d8ce 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java @@ -2,7 +2,9 @@ package com.baeldung.map.concurrenthashmap; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import org.junit.Assert; @@ -11,13 +13,29 @@ import org.junit.Test; public class NullAllowInMapUnitTest { @Test - public void allowNullKey_In_SynchronizedMap() { + public void allowNullKey_In_HashMapBackedSynchronizedMap() { Map map = Collections .synchronizedMap(new HashMap()); map.put(null, 1); Assert.assertTrue(map.get(null).equals(1)); } + + @Test(expected = NullPointerException.class) + public void allowNullKey_In_TreeMapBackedSynchronizedMap() { + Map map = Collections.synchronizedMap(new TreeMap()); + map.put(null, 1); + Assert.assertTrue(map.get(null).equals(1)); + } + + @Test + public void allowNullKey_In_LinkedHashMapBackedSynchronizedMap() { + Map map = Collections + .synchronizedMap(new LinkedHashMap()); + map.put(null, 1); + Assert.assertTrue(map.get(null).equals(1)); + } + @Test(expected = NullPointerException.class) public void allowNullKey_In_ConcurrentHasMap() { Map map = new ConcurrentHashMap<>(); @@ -25,12 +43,27 @@ public class NullAllowInMapUnitTest { } @Test - public void allowNullValue_In_SynchronizedMap() { + public void allowNullValue_In_HashMapBackedSynchronizedMap() { Map map = Collections.synchronizedMap(new HashMap()); map.put("1", null); Assert.assertNull(map.get("1")); } + @Test + public void allowNullValue_In_TreeMapBackedSynchronizedMap() { + Map map = Collections.synchronizedMap(new TreeMap()); + map.put("1", null); + Assert.assertNull(map.get("1")); + } + + @Test + public void allowNullValue_In_LinkedHashSynchronizedMap() { + Map map = Collections + .synchronizedMap(new LinkedHashMap()); + map.put("1", null); + Assert.assertNull(map.get("1")); + } + @Test(expected = NullPointerException.class) public void allowNullValue_In_ConcurrentHasMap() { Map map = new ConcurrentHashMap<>(); From 819d1bda5cae4215fbb9522e75f57b90c0796f9b Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Mon, 21 Dec 2020 02:06:26 +0530 Subject: [PATCH 8/8] BAEL-4686: fixed review comments --- .../NullAllowInMapUnitTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java index c5fc57d8ce..594e8ec3b4 100644 --- a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/concurrenthashmap/NullAllowInMapUnitTest.java @@ -13,7 +13,7 @@ import org.junit.Test; public class NullAllowInMapUnitTest { @Test - public void allowNullKey_In_HashMapBackedSynchronizedMap() { + public void givenHashMapBackedSynchronizedMap_whenNullAsKey_thenNoError() { Map map = Collections .synchronizedMap(new HashMap()); map.put(null, 1); @@ -22,14 +22,14 @@ public class NullAllowInMapUnitTest { @Test(expected = NullPointerException.class) - public void allowNullKey_In_TreeMapBackedSynchronizedMap() { + public void givenTreeMapBackedSynchronizedMap_whenNullAsKey_thenException() { Map map = Collections.synchronizedMap(new TreeMap()); map.put(null, 1); Assert.assertTrue(map.get(null).equals(1)); } @Test - public void allowNullKey_In_LinkedHashMapBackedSynchronizedMap() { + public void givenLinkedHashMapBackedSynchronizedMap_whenNullAsKey_thenNoError() { Map map = Collections .synchronizedMap(new LinkedHashMap()); map.put(null, 1); @@ -37,27 +37,27 @@ public class NullAllowInMapUnitTest { } @Test(expected = NullPointerException.class) - public void allowNullKey_In_ConcurrentHasMap() { + public void givenConcurrentHasMap_whenNullAsKey_thenException() { Map map = new ConcurrentHashMap<>(); map.put(null, 1); } @Test - public void allowNullValue_In_HashMapBackedSynchronizedMap() { + public void givenHashMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { Map map = Collections.synchronizedMap(new HashMap()); map.put("1", null); Assert.assertNull(map.get("1")); } @Test - public void allowNullValue_In_TreeMapBackedSynchronizedMap() { + public void givenTreeMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { Map map = Collections.synchronizedMap(new TreeMap()); map.put("1", null); Assert.assertNull(map.get("1")); } @Test - public void allowNullValue_In_LinkedHashSynchronizedMap() { + public void givenLinkedHashMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { Map map = Collections .synchronizedMap(new LinkedHashMap()); map.put("1", null); @@ -65,7 +65,7 @@ public class NullAllowInMapUnitTest { } @Test(expected = NullPointerException.class) - public void allowNullValue_In_ConcurrentHasMap() { + public void givenConcurrentHasMap_whenNullAsValue_thenException() { Map map = new ConcurrentHashMap<>(); map.put("1", null); }