java的CAS怎麼應用
CAS解釋:
CAS(compare and swap),比較並交換。可以解決多執行緒並行情況下使用鎖造成效能損耗的一種機制.CAS 運算包含三個運算元—記憶體位置(V)、預期原值(A)和新值(B)。如果記憶體位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。一個執行緒從主記憶體得到num值,並對num進行操作,寫入值的時候,執行緒會把第一次取到的num值和主記憶體中num值進行比較,如果相等,就會改變後的num寫入主內存,如果不相等,則一直循環對比,知道成功為止。
CAS產生:
在修飾共享變數的時候經常使用volatile關鍵字,但是volatile值有可見性和禁止指令重拍(有序性),無法保證原子性。雖然在單線程中沒有問題,但是多線程就會出現各種問題,造成現場不安全的現象。所以jdk1.5後產生了CAS利用CPU原語(不可分割,連續不中斷)保證現場操作原子性。
CAS應用程式:
在JDK1.5 中新增java.util.concurrent(JUC)就是建立在CAS之上的。相對於synchronized這種鎖定機制,CAS是非阻塞演算法的常見實作。所以JUC在性能上有了很大的提升。
例如AtomicInteger類,AtomicInteger是線程安全的的,下面是源碼
進入unsafe看到do while自循環,這裡的自循環,就是在判斷預期原值如果與原來的值不符合,會再循環取原值,再走CAS流程,直到能夠把新值賦值成功。
CAS優點
cas是一種樂觀鎖的思想,而且是一種非阻塞的輕量級的樂觀鎖,非阻塞式是指一個執行緒的失敗或掛起不應該影響其他執行緒的失敗或掛起的演算法。
CAS 缺點
循環時間長開銷大,佔用CPU資源。如果自旋鎖長時間不成功,會為CPU帶來很大的開銷。如果JVM能支援處理器提供的pause指令那麼效率會有一定的提升,pause指令有兩個作用,第一它可以延遲管線執行指令(de-pipeline),使CPU不會消耗過多的執行資源,延遲的時間取決於實作的版本,在某些處理器上延遲時間是零。第二它可以避免在退出循環的時候因記憶體順序衝突(memory order violation)而引起CPU管線被清空(CPU pipeline flush),從而提高CPU的執行效率。
只能保證一個共享變數的原子操作。當對一個共享變數執行操作時,我們可以使用循環CAS的方式來保證原子操作,但是對多個共享變數操作時,循環CAS就無法保證操作的原子性,這個時候就可以用鎖,或者有一個取巧的辦法,就是把多個共享變數合併成一個共享變數來操作。例如有兩個共享變數i=2,j=a,合併一下ij=2a,然後用CAS來操作ij。從Java1.5開始JDK提供了AtomicReference類別來保證引用物件之間的原子性,你可以把多個變數放在一個物件裡來進行CAS運算。
ABA問題
解決ABA問題(如果值考慮收尾,不考慮過程可以忽略改問題)
新增版本號碼
AtomicStampedReference
從Java1.5開始JDK的atomic套件裡提供了一個類別AtomicStampedReference來解決ABA問題。這個類別的compareAndSet方法作用是先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如 全部相等,則以原子方式將該引用和該標誌的值設為給定的更新值。
CAS使用的時機
線程數較少、等待時間短可以採用自旋鎖進行CAS嘗試拿鎖,較於synchronized高效。
執行緒數較大、等待時間長,不建議使用自旋鎖,佔用CPU較高
以上是java的CAS怎麼應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4
