ConcurrentHashMap的源码分析-addCount
生活随笔
收集整理的這篇文章主要介紹了
ConcurrentHashMap的源码分析-addCount
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在putVal最后調用addCount的時候,傳遞了兩個參數,分別是1和binCount(鏈表長度),看看addCount方法里面做了什么操作
x表示這次需要在表中增加的元素個數,check參數表示是否需要進行擴容檢查,大于等于0都需要進行檢查
private final void addCount(long x, int check) { CounterCell[] as; long b, s;判斷counterCells是否為空,1. 如果為空,就通過cas操作嘗試修改baseCount變量,對這個變量進行原子累加操作(做這個操作的意義是:如果在沒有競爭的情況下,仍然采用baseCount來記錄元素個數) 2. 如果cas失敗說明存在競爭,這個時候不能再采用baseCount來累加,而是通過CounterCell來記錄if ((as = counterCells) != null || !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)){ CounterCell a; long v; int m; boolean uncontended = true;//是否沖突標識,默認為沒有沖突 這里有幾個判斷 1. 計數表為空則直接調用fullAddCount 2. 從計數表中隨機取出一個數組的位置為空,直接調用fullAddCount 3. 通過CAS修改CounterCell隨機位置的值,如果修改失敗說明出現并發情況(這里又用到了一種巧妙的方法),調用fullAndCount Random在線程并發的時候會有性能問題以及可能會產生相同的隨機數,ThreadLocalRandom.getProbe可以解決這個問題,并且性能要比Random高 if (as == null || (m = as.length - 1) < 0 || (a = as[ThreadLocalRandom.getProbe() & m]) == null || !(uncontended = U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) { fullAddCount(x, uncontended);//執行fullAddCount方法 return; } if (check <= 1)//鏈表長度小于等于1,不需要考慮擴容 return; s = sumCount();//統計ConcurrentHashMap元素個數 } //…. }?
總結
以上是生活随笔為你收集整理的ConcurrentHashMap的源码分析-addCount的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ConcurrentHashMap的源码
- 下一篇: ConcurrentHashMap的源码