生活随笔
收集整理的這篇文章主要介紹了
理解CAS操作
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CAS:Compare and Swap
即就是:比較并且交換 一種硬件對并發的支持,針對多處理器操作而設計的處理器中的一種特殊指令,用于管理對共享數據的并發訪問。 解決共享變量的內存可見性問題 樂觀鎖 采用CAS實現的類:java.util.concurrent.atomic包下:AtomicInteger。
內存可見性
Java內存模型規定了所有的變量都存儲在主內存中。每條線程中還有自己的工作內存,線程的工作內存中保存了被該線程所使用到的變量這些變量是從主內存中拷貝而來。線程對變量的所有操作(讀取,賦值)都必須工作內存中進行。不同線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成。 線程之間無法直接獲取訪問對方的工作空間的變量,線程之間的變量傳遞需要通過主存完成。這就涉及到,主存變量更新不及時,線程訪問變量獲取的是舊值 CAS 是一種無鎖的非阻塞算法的實現。
非阻塞算法
非阻塞算法(nonblocking algorithms):一個線程的失敗或者掛起不應該影響其他線程的失敗或掛起的算法。 Java? 5.0 第一次讓使用 Java 語言開發非阻塞算法成為可能,java.util.concurrent 包充分地利用了這個功能。非阻塞算法屬于并發算法,它們可以安全地派生它們的線程,不通過鎖定派生,而是通過低級的原子性的硬件原生形式 —— 例如比較和交換。非阻塞算法的設計與實現極為困難,但是它們能夠提供更好的吞吐率,對生存問題(例如死鎖和優先級反轉)也能提供更好的防御。 在不只一個線程訪問一個互斥的變量時,所有線程都必須使用同步,否則就可能會發生一些非常糟糕的事情。Java 語言中主要的同步手段就是 synchronized關鍵字(也稱為內在鎖),它強制實行互斥,確保執行synchronized塊的線程的動作,能夠被后來執行受相同鎖保護的 synchronized 塊的其他線程看到。在使用得當的時候,內在鎖可以讓程序做到線程安全,但是在使用鎖定保護短的代碼路徑,而且線程頻繁地爭用鎖的時候,鎖定可能成為相當繁重的操作。 原子變量提供了原子性的讀-寫-修改操作,可以在不使用鎖的情況下安全地更新共享變量。原子變量的內存語義與volatile變量類似,但是因為它們也可以被原子性地修改,所以可以把它們用作不使用鎖的并發算法的基礎。
synchronized:悲觀鎖/獨占鎖
CAS實現原理
CAS 包含了 3 個操作數: 需要讀寫的內存值 V 進行比較的值 A 擬寫入的新值 B 當且僅當 V 的值等于 A 時, CAS 通過原子方式用新值 B 來更新 V 的 值,否則不會執行任何操作。
concurrent包下原理
1.首先,聲明共享變量為volatile; 2.然后,使用CAS的原子條件更新來實現線程之間的同步; 3.同時,配合以volatile的讀/寫和CAS所具有的volatile讀和寫的內存語義來實現線程之間的通信。
CAS缺點:
CAS雖然很高效的解決原子操作,但是CAS仍然存在三大問題。ABA問題,循環時間長開銷大和只能保證一個共享變量的原子操作。 ABA問題。因為CAS需要在操作值的時候檢查下值有沒有發生變化,如果沒有發生變化則更新,但是如果一個值原來是A,變成了B,又變成了A,那么使用CAS進行檢查時會發現它的值沒有發生變化,但是實際上卻變化了。ABA問題的解決思路就是使用版本號。在變量前面追加上版本號,每次變量更新的時候把版本號加一,那么A-B-A 就會變成1A-2B-3A。從Java1.5開始JDK的atomic包里提供了一個類AtomicStampedReference來解決ABA問題。 循環時間長開銷大。自旋CAS如果長時間不成功,會給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操作。
總結
以上是生活随笔 為你收集整理的理解CAS操作 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。