java 的CAS

CAS:什麼是 CAS 機制?
cas目的是實現原子操做解釋一下:
"原子操做(atomic operation)是不須要synchronized",這是多線程編程的老生常談了。所謂原子操做是指不會被線程調度機制打斷的操做;這種操做一旦開始,就一直運行到結束,中間不會有任何 context switch (切 [1] 換到另外一個線程)。 這是百度百科的解釋
意思就是這個狀態不會被中間態打斷,例如銀行轉帳機制,一個帳號扣錢了,收錢帳戶也必定要收錢,不能中斷
在java中原子操做 用於多線程的操做場景避免一個共享變量沒有達到預期值java

參見一個例子不安全場景:數據庫

  

這個結果 count不必定是200,由於存在多線程的競爭問題可能小於200,若是把run方法裏面 加上synchronized代碼塊後每一個線程的運行的狀態不會受別的線程影響,實現了原子操做,最中結果必定是200.  編程

java.util.concurrent.atomic包下 有一系列原子類安全

 

這中操做最後也是200,由於原子類專門解決了這個問題多線程

java.util.concurrent.atomic 包下的類就是解決CAS的問題的,都是原子類。併發

原子類中的value 利用了volatile 實現的變量值共享。高併發

,核心原理是:CAS機制當中使用了3個基本操做數:內存地址V,舊的預期值A,要修改的新值B。性能

每次更新的時候舊值都要與內存值比較,不一致會更新失敗,而後利用內存值繼續更新(出現了自旋操做,在高併發下比較危險會嚴重消耗cpu資源)atom

好比第二個線程運行到97的時候 第一個線程因爲反應較慢才運行到5那麼當5自增的時候必定會失敗內存值與舊值不一致,因此進行自旋從97開始到98,第二個線程開始運行98舊值是97因此也會失敗開始自旋到98,以此類推就實現了交替自增最終結果是200..net

參見:https://ss.csdn.net/p?https://mmbiz.qpic.cn/mmbiz_jpg/NtO5sialJZGpfMM4tNG7D3k05o337rpShibke60ZSQ8jQuoQMdXK7fcyLkkDGS2EfOiahzQQS9DPHmjsXcB8ibWKdg/0?wx_fmt=jpeg

圖文並茂的講解。

cas是樂觀鎖,synchronized 是悲觀鎖,  在大併發下synchronized 的使用要比cas好些(CAS自旋的機率會比較大,從而浪費更多的CPU資),併發不大的時候cas性能好(不須要切換線程,操做自旋概率較少)

cas存在的問題:

ABA問題,若是 一個值是A, 被線程2變成了B, 被線程2或者其它的線程又給變回了A, 那麼此時線程1操做的時候檢查到的仍是A,就認爲沒有變化,則執行更新,

AtomicStampedReference類解決了該問題,加入了版本號的解決方式。相似數據庫的樂觀鎖加入版本號機制。

只能保證一個共享變量的原子操做,AtomicReference類可以知足多個變量的原子操做。

相關文章
相關標籤/搜索