多線程系列提高(5)--幾種重要的併發容器類

一、ConcurrentHashMap

與hashMap一樣,ConcurrentHashMap也是一個基於散列的Map,但它使用了一種完全不同的加鎖策略來提高併發性和伸縮性。ConcurrentHashMap並不是將每個方法都在同一個鎖上同步並使得每次只能有一個線程訪問容器,而是採用一種粒度更細的加鎖機制來實現更大程度的共享,這種機制叫做分段鎖,默認是分成16段。在這種機制下,任意數量的讀取線程可以併發的訪問Map,執行讀取操作的線程和執行寫入操作的線程可以併發的訪問map,並且一定數量的寫入線程可以併發的修改Map,實現了在併發訪問環境下將實現更高的吞吐量,而在單線程環境中只損失非常小的性能。
ConcurrentHashMap返回的迭代器具有弱一致性,而並非“及時失敗”,弱一致性的迭代器可以容忍併發的修改,當創建迭代器時會遍歷已有的元素,並可以(但是不保證)在迭代器被構造後將修改操作反映給容器。

二、CopyOnWriteArrayList

CopyOnWriteArrayList用於替代同步的List,在某些情況下它提供了更好的併發性能,並且在迭代期間不需要對容器進行加鎖或者複製(類似的,CopyOnWriteArraySet替代同步Set)。
“寫入時複製(CopyOnWrite)”容器的安全性在於:只要正確的發佈一個事實不可變的對象,那麼在訪問該對象時就不再需要進一步的同步,在每次修改時,都會創建並重新發佈一個新的容器副本,從而實現可變性。“寫入時複製”容器的迭代器保留一個指向底層基礎數組的引用,這個數組當前位於迭代器的起始位置,由於它不會被修改,因此在其對進行同步時只需確保數組內容的可見性。“寫入時複製”容器返回的迭代器不會拋出COncurrentModificationException,並且返回的元素與迭代器創建時的元素完全一致,而不必考慮之後修改操作所帶來的影響。
每當修改容器時都會複製底層數組,這需要一定的開銷,特別是當容器的規模較大時,僅當迭代操作遠遠多於修改操作時,才應該使用“寫入時複製”容器。這個準則很好的描述了許多事件通知系統:在分發通知時需要迭代已註冊監聽器鏈表,並調用每一個監聽器,在大多數情況下,註冊和註銷事件監聽器的操作遠少於接收事件通知的操作。

發佈了104 篇原創文章 · 獲贊 56 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章