https://www.ibm.com/developerworks/cn/java/j-concurrent/
https://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/index.html
總結(jié)
ConcurrentHashMap 是一個(gè)并發(fā)散列映射表的實(shí)現(xiàn),相比于 HashTable 和用同步包裝器包裝的 HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 擁有更高的并發(fā)性。
HashTable缺點(diǎn)
在 HashTable 和由同步包裝器包裝的 HashMap 中桩匪,使用一個(gè)全局的鎖來(lái)同步不同線程間的并發(fā)訪問(wèn)。同一時(shí)間點(diǎn)邦泄,只能有一個(gè)線程持有鎖撬腾,也就是說(shuō)在同一時(shí)間點(diǎn)枫甲,只能有一個(gè)線程能訪問(wèn)容器椅亚。這雖然保證多線程間的安全并發(fā)訪問(wèn)限番,但同時(shí)也導(dǎo)致對(duì)容器的訪問(wèn)變成串行化的了。
在使用鎖來(lái)協(xié)調(diào)多線程間并發(fā)訪問(wèn)的模式下呀舔,減小對(duì)鎖的競(jìng)爭(zhēng)可以有效提高并發(fā)性弥虐。有兩種方式可以減小對(duì)鎖的競(jìng)爭(zhēng):
- 減小請(qǐng)求 同一個(gè)鎖的 頻率。
- 減少持有鎖的 時(shí)間。
ConcurrentHashMap 的高并發(fā)性主要來(lái)自于三個(gè)方面:
- 用分離鎖實(shí)現(xiàn)多個(gè)線程間的更深層次的共享訪問(wèn)霜瘪。
- 用 HashEntery 對(duì)象的不變性來(lái)降低執(zhí)行讀操作的線程在遍歷鏈表期間對(duì)加鎖的需求珠插。
- 通過(guò)對(duì)同一個(gè) Volatile 變量的寫(xiě) / 讀訪問(wèn),協(xié)調(diào)不同線程間讀 / 寫(xiě)操作的內(nèi)存可見(jiàn)性粥庄。
使用分離鎖丧失,減小了請(qǐng)求 同一個(gè)鎖的頻率豺妓。
通過(guò) HashEntery 對(duì)象的不變性及對(duì)同一個(gè) Volatile 變量的讀 / 寫(xiě)來(lái)協(xié)調(diào)內(nèi)存可見(jiàn)性惜互,使得 讀操作大多數(shù)時(shí)候不需要加鎖就能成功獲取到需要的值。由于散列映射表在實(shí)際應(yīng)用中大多數(shù)操作都是成功的 讀操作琳拭,所以 2 和 3 既可以減少請(qǐng)求同一個(gè)鎖的頻率训堆,也可以有效減少持有鎖的時(shí)間。
通過(guò)減小請(qǐng)求同一個(gè)鎖的頻率和盡量減少持有鎖的時(shí)間 白嘁,使得 ConcurrentHashMap 的并發(fā)性相對(duì)于 HashTable 和用同步包裝器包裝的 HashMap有了質(zhì)的提高坑鱼。