1. 程式人生 > >CAS演算法的理解及應用

CAS演算法的理解及應用

應用
眾所周知,Java中有許多執行緒安全類,比如執行緒安全的集合類。從Java5開始,在java.util.concurrent包下提供了大量支援高效併發訪問的集合介面和實現類。如:ConcurrentMap、ConcurrentLinkedQueue等執行緒安全集合。
引入問題
那麼問題來了,這些執行緒安全類的底層是怎麼保證執行緒安全的,你可能會想到是不是使用同步程式碼鎖synchronized?其實不是。

引入概念
這些執行緒安全類底層實現使用一種稱為CAS的演算法,(Compare And Swap)比較交換。這個演算法相對synchronized是比較“樂觀的”,它不會像synchronized一樣,當一個執行緒訪問共享資料的時候,別的執行緒都在阻塞。

實現原理
線上程開啟的時候,會從主存中給每個執行緒拷貝一個變數副本到執行緒各自的執行環境中,CSA演算法中包含三個引數(V,E,N),V表示要更新的變數(也就是從主存中拷貝過來的值)、E表示預期的值、N表示新值。

在這裡插入圖片描述

實現過程
假如現在有兩個執行緒t1,t2,,他們各自的執行環境中都有共享變數的副本V1、V2,預期值E1、E2,預期主存中的值還沒有被改變,假設現在在併發環境,並且t1先拿到了執行許可權,失敗的執行緒並不會被掛起,而是被告知這次競爭中失敗,並可以再次發起嘗試,然後t1比較預期值E1和主存中的V,發現E1=V,說明預期值是正確的,執行N1=V1+1,並將N1的值傳入主存。這時候貯存中的V=21,然後t2又緊接著拿到了執行權,比較E2和主存V的值,由於V已經被t1改為21,所以E2!=V,t2執行緒什麼都不做。

結論
其實就是拿副本中的預期值與主存中的值作比較,如果相等就繼續替換新值,如果不相等就說明主存中的值已經被別的執行緒修改,就什麼都不做。

CAS(比較並交換)是CPU指令級的操作,只有一步原子操作,所以非常快。而且CAS避免了請求作業系統來裁定鎖的問題,不用麻煩作業系統,直接在CPU內部就搞定了