Merge pull request #10276 from amitiw4u/BAEL-4686-ConcurrentVsSynchronizedMap
Bael 4686 concurrent vs synchronized map
This commit is contained in:
		
						commit
						96ca95aee1
					
				| @ -15,7 +15,11 @@ | |||||||
|     </parent> |     </parent> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
|          |         <dependency> | ||||||
|  |             <groupId>org.openjdk.jmh</groupId> | ||||||
|  |             <artifactId>jmh-core</artifactId> | ||||||
|  |             <version>${jmh-core.version}</version> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|  | |||||||
| @ -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<String, Integer> map = Collections.synchronizedMap(new HashMap<String, Integer>()); | ||||||
|  |         performReadAndWriteTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Benchmark | ||||||
|  |     public void randomReadAndWriteConcurrentHashMap() { | ||||||
|  |         Map<String, Integer> map = new ConcurrentHashMap<>(); | ||||||
|  |         performReadAndWriteTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private void performReadAndWriteTest(final Map<String, Integer> 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<String, Integer> map = Collections.synchronizedMap(new HashMap<String, Integer>()); | ||||||
|  |         performWriteTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Benchmark | ||||||
|  |     public void randomWriteConcurrentHashMap() { | ||||||
|  |         Map<String, Integer> map = new ConcurrentHashMap<>(); | ||||||
|  |         performWriteTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private void performWriteTest(final Map<String, Integer> 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<String, Integer> map = Collections.synchronizedMap(new HashMap<String, Integer>()); | ||||||
|  |         performReadTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Benchmark | ||||||
|  |     public void randomReadConcurrentHashMap() { | ||||||
|  |         Map<String, Integer> map = new ConcurrentHashMap<>(); | ||||||
|  |         performReadTest(map); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private void performReadTest(final Map<String, Integer> 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)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,70 @@ | |||||||
|  | package com.baeldung.map.concurrenthashmap; | ||||||
|  | 
 | ||||||
|  | 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; | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | public class ConcurrentModificationErrorUnitTest { | ||||||
|  | 
 | ||||||
|  |     @Test(expected = ConcurrentModificationException.class) | ||||||
|  |     public void whenRemoveAndAddOnHashMap_thenConcurrentModificationError() { | ||||||
|  |         Map<Integer, String> map = new HashMap<>(); | ||||||
|  |         map.put(1, "baeldung"); | ||||||
|  |         map.put(2, "HashMap"); | ||||||
|  |         Map<Integer, String> synchronizedMap = Collections.synchronizedMap(map); | ||||||
|  |         Iterator<Entry<Integer, String>> iterator = synchronizedMap.entrySet().iterator(); | ||||||
|  |         while (iterator.hasNext()) { | ||||||
|  |             synchronizedMap.put(3, "Modification"); | ||||||
|  |             iterator.next(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test(expected = ConcurrentModificationException.class) | ||||||
|  |     public void whenRemoveAndAddOnTreeMap_thenConcurrentModificationError() { | ||||||
|  |         Map<Integer, String> map = new TreeMap<>(); | ||||||
|  |         map.put(1, "baeldung"); | ||||||
|  |         map.put(2, "HashMap"); | ||||||
|  |         Map<Integer, String> synchronizedMap = Collections.synchronizedMap(map); | ||||||
|  |         Iterator<Entry<Integer, String>> iterator = synchronizedMap.entrySet().iterator(); | ||||||
|  |         while (iterator.hasNext()) { | ||||||
|  |             synchronizedMap.put(3, "Modification"); | ||||||
|  |             iterator.next(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test(expected = ConcurrentModificationException.class) | ||||||
|  |     public void whenRemoveAndAddOnLinkedHashMap_thenConcurrentModificationError() { | ||||||
|  |         Map<Integer, String> map = new LinkedHashMap<>(); | ||||||
|  |         map.put(1, "baeldung"); | ||||||
|  |         map.put(2, "HashMap"); | ||||||
|  |         Map<Integer, String> synchronizedMap = Collections.synchronizedMap(map); | ||||||
|  |         Iterator<Entry<Integer, String>> iterator = synchronizedMap.entrySet().iterator(); | ||||||
|  |         while (iterator.hasNext()) { | ||||||
|  |             synchronizedMap.put(3, "Modification"); | ||||||
|  |             iterator.next(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenRemoveAndAddOnConcurrentHashMap_thenNoError() { | ||||||
|  |         Map<Integer, String> map = new ConcurrentHashMap<>(); | ||||||
|  |         map.put(1, "baeldung"); | ||||||
|  |         map.put(2, "HashMap"); | ||||||
|  |         Iterator<Entry<Integer, String>> iterator = map.entrySet().iterator(); | ||||||
|  |         while (iterator.hasNext()) { | ||||||
|  |             map.put(3, "Modification"); | ||||||
|  |             iterator.next(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(3, map.size()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,73 @@ | |||||||
|  | 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; | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | public class NullAllowInMapUnitTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenHashMapBackedSynchronizedMap_whenNullAsKey_thenNoError() { | ||||||
|  |         Map<String, Integer> map = Collections | ||||||
|  |                 .synchronizedMap(new HashMap<String, Integer>()); | ||||||
|  |         map.put(null, 1); | ||||||
|  |         Assert.assertTrue(map.get(null).equals(1)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     @Test(expected = NullPointerException.class) | ||||||
|  |     public void givenTreeMapBackedSynchronizedMap_whenNullAsKey_thenException() { | ||||||
|  |         Map<String, Integer> map = Collections.synchronizedMap(new TreeMap<String, Integer>()); | ||||||
|  |         map.put(null, 1); | ||||||
|  |         Assert.assertTrue(map.get(null).equals(1)); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void givenLinkedHashMapBackedSynchronizedMap_whenNullAsKey_thenNoError() { | ||||||
|  |         Map<String, Integer> map = Collections | ||||||
|  |                 .synchronizedMap(new LinkedHashMap<String, Integer>()); | ||||||
|  |         map.put(null, 1); | ||||||
|  |         Assert.assertTrue(map.get(null).equals(1)); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test(expected = NullPointerException.class) | ||||||
|  |     public void givenConcurrentHasMap_whenNullAsKey_thenException() { | ||||||
|  |         Map<String, Integer> map = new ConcurrentHashMap<>(); | ||||||
|  |         map.put(null, 1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void givenHashMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { | ||||||
|  |         Map<String, Integer> map = Collections.synchronizedMap(new HashMap<String, Integer>()); | ||||||
|  |         map.put("1", null); | ||||||
|  |         Assert.assertNull(map.get("1")); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void givenTreeMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { | ||||||
|  |         Map<String, Integer> map = Collections.synchronizedMap(new TreeMap<String, Integer>()); | ||||||
|  |         map.put("1", null); | ||||||
|  |         Assert.assertNull(map.get("1")); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void givenLinkedHashMapBackedSynchronizedMap_whenNullAsValue_thenNoError() { | ||||||
|  |         Map<String, Integer> map = Collections | ||||||
|  |                 .synchronizedMap(new LinkedHashMap<String, Integer>()); | ||||||
|  |         map.put("1", null); | ||||||
|  |         Assert.assertNull(map.get("1")); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test(expected = NullPointerException.class) | ||||||
|  |     public void givenConcurrentHasMap_whenNullAsValue_thenException() { | ||||||
|  |         Map<String, Integer> map = new ConcurrentHashMap<>(); | ||||||
|  |         map.put("1", null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user