當前位置:編程學習大全網 - 源碼下載 - ConcurrentHashMap如何實現高效地線程安全?

ConcurrentHashMap如何實現高效地線程安全?

如何保證容器是線程安全的? ConcurrentHashMap如何實現高效地線程安全?

Java提供了不同層面的線程安全支持。在傳統集合框架內部,除了Hashtable等同步容器,還提供了所謂的同步包裝器(Synchronized Wrapper),我們可以調用Collections工具類提供的包裝方法,來獲取壹個同步的包裝容器(如Collections.synchronizedMap),但是它們都是利用非常粗粒度的同步方式,在高並發情況下,性能比較低下。

另外,更加普遍的選擇是利用並發包提供的線程安全容器類,它提供了:

各種並發容器,比如ConcurrentHashMap、 CopyOnWriteArrayList。

各種線程安全隊列(Queue/Deque),如ArrayBlockingQueue、 SynchronousQueue。

各種有序容器的線程安全版本等。

1.為什麽需要ConcurrentHashMap?

Hashtable本身比較低效,因為它的實現基本就是將put、 get、 size等各種方法加上“synchronized”。簡單來說,這就導致了所有並發操作都要競爭同壹把鎖,壹個線程在進行同

步操作時,其他線程只能等待,大大降低了並發操作的效率。

個人理解

就是更細粒度的加鎖機制來實現更大程度的***享。

2.ConcurrentHashMap分析

ConcurrentHashMap的設計實現其實壹直在演化。

1.7

put加鎖

通過分段加鎖segment,壹個hashmap裏有若幹個segment,每個segment裏有若幹個桶,桶裏存放K-V形式的鏈表, put數據時通過key哈希得到該元素要添加到的segment,

然後

對segment進行加鎖,然後在哈希,計算得到給元素要添加到的桶,然後遍歷桶中的鏈表,替換或新增節點到桶中

size

分段計算兩次,兩次結果相同則返回,否則對所以段加鎖重新計算

1.8

put CAS 加鎖

1.8中不依賴與segment加鎖,segment數量與桶數量壹致;

首先判斷容器是否為空,為空則進行初始化利用volatile的sizeCtl作為互斥手段,如果發現競爭性的初始化,就暫停在那裏,等待條件恢復,否則利用CAS設置排他標誌

(U.compareAndSwapInt(this, SIZECTL, sc, -1)) ;否則重試

對key hash計算得到該key存放的桶位置,判斷該桶是否為空,為空則利用CAS設置新節點

否則使用synchronize加鎖,遍歷桶中數據,替換或新增加點到桶中

最後判斷是否需要轉為紅黑樹,轉換之前判斷是否需要擴容

size

利用LongAdd累加計算

ConcurrentHashMap使用要點

ConcurrentHashMap使用要點

ConcurrentHashMap允許壹邊更新、壹邊遍歷,也就是說在Iterator對象遍歷的時候,ConcurrentHashMap也可以進行remove,put操作,且遍歷的數據會隨著remove,put操作產出變化

  • 上一篇:求壹個用C語言寫的網絡音樂播放器,類似千千聽歌的源代碼。
  • 下一篇:請問重慶市比較好的IT外包公司有哪些?介紹壹下。我們公司電腦經常出問題呢!
  • copyright 2024編程學習大全網