ConcurrentHashMap vs Hashtable vs Synchronized Map#
雖然這三個類都能多線程安全地在 Java 並發程序中使用,但是他們之間有著標誌性的不同,主要體現在他們是怎麼實現他們的線程安全的。
HashTable 在 Java1.1 就已經出現了,使用同步的方法來實現線程安全,Hashtable 裡的方法都是 Synchronized 的,這使得它在線程增多的時候會變得很慢。
Synchronized Map 和 Hashtable 並沒有太大的不同,以及它在並發編程的時候提供了相似的性能。hashtable 和 Synchronized Map 之間的唯一不同在於後者可以使用Collections.synchronizedMap()
方法把任何的 Map 變成同步版本。
在另一方面,ConcurrentHashMap 是特別設計出來給並發編程使用的。默認地,它同時允許 16 個線程在沒有任何外部的同步措施下讀寫 Map。
由於內部實現了分段鎖,所以有相當的拓展性。和 SynchronizedMap 和 Hashtable 不一樣,它不會把整個 Map 鎖住,而是,把 map 分段(Segment),然後再給他們都加上鎖。
所以在讀(get 不加鎖)比寫的性能要高
老實說,Collections 類作為 JavaAPI 的核心類,我認為,審慎地使用它們是一種藝術。我的個人經驗是,使用 Array List 代替不必要地 Vector 之類的可以提高 Java 應用的性能之類的。
在 Java5 之前,Java Collection 框架的一個問題在於缺少可拓展性。
在多線程 Java 應用中像 Hash table 和 Vector 很快會成瓶頸;在 Java1.5 後提出了拓展性,並推薦了一線不錯的並發容器,在數據量大的時候能保持高效。
遺留的系統,像電子貿易系統以有能快速訪問儲存的數據的能力作為支持(註:指使用能支持快速高並發的容器)。
在這篇說明中,我們討論了 ConcurrentHashMap, Hashtable, HashMap 和 synchronized Map ,還探討了在 Java 中 ConcurrentHashMap 、 Hashtable
和 synchronized Map 的不同。在這篇博客中也討論了 Hashtable, HashMap 的不同,這些能在面試的時候幫你回答一些問題。
為什麼需要 ConcurrentHashMap 和 CopyOnWriteArrayList#
同步的容器,如 Hashtable, Vector, Collections.synchronizedMap () 和 Collections.synchronizedList (), 提供了可選的線程安全的 Map 或 List 實現。
但是,一些因子讓他們不是很適合用在高並發程序中,比如,它們範圍很大的鎖會妨礙他們的拓展性,以及通常在迭代訪問的時候需要鎖住整個容器來防止 ConcurrentModificationException。
ConcurrentHashMap 和 CopyOnWriteArrayList 的實現提供了更高的並發的同時保證了線程安全, 以最小的代價妥協調用者。
ConcurrentHashMap 和 CopyOnWriteArrayList 並不是必要在哪都要用,你也可以使用 HashMap 或 ArrayList, 但是要在特定的情況下(註:並發安全)。在很多並發程序中使用它們可以得到好處。
ConcurrentHashMap 和 Hashtable 的不同#
所以 ConcurrentHashMap 和 Hashtable 的不同在哪呢,都能用在多線程環境,但是 當 Hashtable 的大小變大的時候性能會有可觀的消耗,因為在訪問的時候會給整個容器加鎖。
ConcurrentHashMap 會給數據分段,不管數據量多大,只用關心被加鎖的範圍。在保證線程安全的前提下,很多其他的讀線程在迭代完成之前能夠訪問容器。
總結一下,在迭代的時候 ConcurrentHashMap 只會鎖住 map 的一部分, 但是 HashMap 會鎖住整個 map. 這幅圖清晰的表達了 Java ConcurrentHashMap 的內部工作原理。
ConcurrentHashMap 和 Collections.synchronizedMap 的不同#
ConcurrentHashMap 為了並發設計的 並提升了性能 ,HashMap 原生狀態下是非同步的 ,使用 synchronized Map 可以包裹它讓它變成同步容器。 有一些 ConcurrentHashMap 和 Collections.synchronizedMap 的不同:
ConcurrentHashMap 不允許 null 鍵 或 null 值 , synchronized HashMap 允許一個 null 鍵.