AtomicLong 與 LongAdder(CAS機制的優化)
執行緒安全性-原子性-CAS
LongAdder是java8為我們提供的新的類,跟AtomicLong有相同的效果。是對CAS機制的優化。
AtomicLong:
//變數宣告
public static AtomicLong count = new AtomicLong(0);
//變數操作
count.incrementAndGet();
//變數取值
count.get();
LongAdder:
//變數宣告
public static LongAdder count = new LongAdder();
//變數操作
count.increment();
//變數取值
count
為什麼有了AtomicLong還要新增一個LongAdder呢?
原因是:CAS底層實現是在一個死迴圈中不斷地嘗試修改目標值,直到修改成功。如果競爭不激烈的時候,修改成功率很高,否則失敗率很高。在失敗的時候,這些重複的原子性操作會耗費效能。(不停的自旋,進入一個無限重複的迴圈中)
知識點: 對於普通型別的long、double變數,JVM允許將64位的讀操作或寫操作拆成兩個32位的操作。
核心思想:將熱點資料分離。
比如說它可以將AtomicLong內部的內部核心資料value分離成一個陣列,每個執行緒訪問時,通過hash等演算法對映到其中一個數字進行計數,而最終的計數結果則為這個陣列的求和累加,其中熱點資料value會被分離成多個單元的cell,每個cell獨自維護內部的值。當前物件的實際值由所有的cell累計合成,這樣熱點就進行了有效地分離,並提高了並行度。這相當於將AtomicLong的單點的更新壓力分擔到各個節點上。在低併發的時候通過對base的直接更新,可以保障和AtomicLong的效能基本一致。而在高併發的時候通過分散提高了效能。
原始碼:
public void increment() {
add(1L);
}
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
longAccumulate(x, null, uncontended);
}
}
缺點:如果在統計的時候,如果有併發更新,可能會有統計資料有誤差。
實際使用中在處理高併發計數的時候優先使用LongAdder,而不是AtomicLong線上程競爭不激烈的時候,使用AtomicLong會簡單效率更高一些。比如序列號生成(準確性)
大白話聊聊Java併發面試問題之Java 8如何優化CAS效能?
在LongAdder的底層實現中,首先有一個base值,剛開始多執行緒來不停的累加數值,都是對base進行累加的,比如剛開始累加成了base = 5。
併發更新的執行緒數量過多時,施行分段CAS的機制(Cell陣列,每個陣列是一個數值分段)
這時,讓大量的執行緒分別去對不同Cell內部的value值進行CAS累加操作,這樣就把CAS計算壓力分散到了不同的Cell分段數值中了!
這樣就可以大幅度的降低多執行緒併發更新同一個數值時出現的無限迴圈的問題,大幅度提升了多執行緒併發更新數值的效能和效率!
而且他內部實現了自動分段遷移的機制,也就是如果某個Cell的value執行CAS失敗了,那麼就會自動去找另外一個Cell分段內的value值進行CAS操作。
這樣也解決了執行緒空旋轉、自旋不停等待執行CAS操作的問題,讓一個執行緒過來執行CAS時可以儘快的完成這個操作。
最後,如果你要從LongAdder中獲取當前累加的總值,就會把base值和所有Cell分段數值加起來返回給你。
相關文章
- 比AtomicLong更高效的併發計數類LongAdder
- 強大的CAS機制
- android記憶體管理機制與優化Android記憶體優化
- CAS 無鎖式同步機制
- Android效能優化(4):UI渲染機制以及優化Android優化UI
- 併發的核心:CAS 是什麼?Java8是如何優化 CAS 的?Java優化
- Oracle 高效能SQL引擎剖析--SQL優化與調優機制詳解OracleSQL優化
- js 呼叫棧機制與ES6尾呼叫優化介紹JS優化
- 瀏覽器重繪(repaint)重排(reflow)與優化[瀏覽器機制]瀏覽器AI優化
- 技術管理進階——關於成本優化與利益分配機制優化
- Java中的鎖原理、鎖優化、CAS、AQS詳解!Java優化AQS
- CAS、原子操作類的應用與淺析及Java8對其的優化Java優化
- MySQL效能優化(九)-- 鎖機制之行鎖MySql優化
- Java 併發機制底層實現 —— volatile 原理、synchronize 鎖優化機制Java優化
- 談談JUC----------CAS機制及AtomicInteger原始碼分析原始碼
- Golang 的 協程排程機制 與 GOMAXPROCS 效能調優Golang
- LongAdder解析
- longAdder原理
- 觸控事件分發核心機制優化吸收事件優化
- mysql鎖機制總結,以及優化建議MySql優化
- 從CPU Cache出發徹底弄懂volatile/synchronized/cas機制synchronized
- redis的持久化機制Redis持久化
- 效能優化篇 - js事件迴圈機制(event loop)優化JS事件OOP
- iOS objc_msgSend尾呼叫優化機制詳解iOSOBJGse優化
- 前端效能優化(二)——瀏覽器快取機制前端優化瀏覽器快取
- 為什麼Proxy可以優化vue的資料監聽機制優化Vue
- JMM、CAS與volatile
- 如何使用外掛化機制優雅的封裝你的請求hook封裝Hook
- JavaScript執行緒機制與事件機制JavaScript執行緒事件
- Java gc(垃圾回收機制)小結,以及Android優化建議JavaGCAndroid優化
- Android客戶端網路預連線優化機制探究Android客戶端優化
- redis持久化機制Redis持久化
- Node工程-構建優秀的Session機制Session
- 函式宣告與變數宣告的提升機制優先順序問題函式變數
- 淺談JS事件機制與React事件機制JS事件React
- 用遊戲來講序列化與反序列化機制遊戲
- CAS與OAuth2的區別OAuth
- JS的事件物件與事件機制JS事件物件