1. 程式人生 > >Java多線程系列六——Map實現類

Java多線程系列六——Map實現類

coo cut tab for http current color text 加鎖

參考資料:

https://crunchify.com/hashmap-vs-concurrenthashmap-vs-synchronizedmap-how-a-hashmap-can-be-synchronized-in-java/

https://stackoverflow.com/questions/35534906/java-hashmap-getobject-infinite-loop

Map的一些實現類有及其特性

線程安全 特性

Hashtable

Key不能為null

HashMap

讀寫效率最高,但在Java6多線程環境下使用不當可能陷入死循環,進而導致CPU使用率過高(原理可參見:http://coolshell.cn/articles/9606.html)

Collections.synchronizedMap

Collections.SynchronizedMap在Map所有方法基礎上加鎖,效率與HashTable相當

ConcurrentHashMap

采用分段鎖,get一般不加鎖,put分段鎖,key/value不能為null,效率僅次於HashMap

以下代碼測試各類的讀寫效率

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @Description: 測試map */ public class ThreadMapTest { public static void main(String[] args) throws InterruptedException { Map<Integer, Integer> hashtable = new
Hashtable<>(); Map<Integer, Integer> hashmap = new HashMap<>(); Map<Integer, Integer> synchronizedHashMap = Collections.synchronizedMap(new HashMap<>()); Map<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>(); test(hashtable); test(hashmap); test(synchronizedHashMap); test(concurrentHashMap); } private static void test(Map<Integer, Integer> map) throws InterruptedException { int testTimes = 5; long totalTimeMillis = 0; for (int k = 0; k < testTimes; k++) { totalTimeMillis += costTimeMillis(map); } System.out.println("Test " + map.getClass() + " average time " + (totalTimeMillis / testTimes)); } private static long costTimeMillis(Map<Integer, Integer> map) throws InterruptedException { int count = 5; ExecutorService executorService = Executors.newFixedThreadPool(count); long startMillis = System.currentTimeMillis(); for (int i = 0; i < count; i++) { executorService.execute(new Runnable() { @Override public void run() { for (int j = 0; j < 500000; j++) { map.put(0, 0); map.get(0); } } }); } executorService.shutdown(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); return System.currentTimeMillis() - startMillis; } }

輸出結果如下:

Test class java.util.Hashtable average time 267
Test class java.util.HashMap average time 67
Test class java.util.Collections$SynchronizedMap average time 262
Test class java.util.concurrent.ConcurrentHashMap average time 167

Java多線程系列六——Map實現類