高併發(11)-原子操作CAS(Compare And Swap)

前言

上篇文章講解了線程的併發工具類之Semaphore,本文就來講解下關於原子操作。
來了解下什麼原子操作,又如何實現原子操作

什麼是原子操作

原子操作就是一個操作或多個操作,要麼全部執行成功要麼全部執行失敗,不會出現一部分成功一部分失敗的情況。

經典的例子就是轉賬,a給b轉賬100元,a要扣減100,b要增加100,這其中包含了a扣減的操作和b增加的操作,這兩個操作就要就要是原子操作,要麼都成功,要麼都操作。如果不是原子操作,就會出現這樣的問題,比如a扣款了,b卻沒有增加,所以必須兩個操作是原子操作來避免出現問題。

如何實現原子操作

我要怎麼實現原子操作呢,可以使用CAS來實現原子操作。

CAS的原理是什麼

CAS就是比較和交換,利用了現代處理器都支持CAS的指令。在操作前先取出原值,然後進行操作,然後在更新修改後的新值的時候,用原值和內存中的原值進行比較,只有比較相同的的時候,纔會做修改操作,把新值替換原值。而當比較不一致的時候,就不做修改,然後再取出新的原值,重新計算,然後再次判斷,重複這個操作。

原子操作圖
從圖中也可以看出,先取出舊值,然後計算到新值,用舊值和內存中的變量比較,相等則更新,不想等則在循環這個過程。

CAS的問題

CAS也會出現一些問題,一起來看下

ABA問題

什麼是ABA問題?ABA問題怎麼解決?

如果內存中的舊值是A,在更新的時候檢查的值還是A,這個時候能說明其他線程沒有改變過這個值嗎?

但是不一定的,可能某個線程給她改變成了B,然後又改成了A,這個時候其實是改動過的,但是CAS操作就會誤認爲他沒有改變過,但實際上是已經改變了,這個問題就叫做ABA問題。

爲了解決這個問題,就產生了一個版本號的概念,我有一個版本號來標識我修改了幾次,即時在發生ABA這種操作,但是版本號是會隨着變化的,這時候我在判斷值是或否相等時,還會加上版本號是否相等,這就可以解決ABA問題。

開銷問題

什麼是開銷問題?
因爲CAS在計算值是否相等的過程中,使用的自旋,當判斷的值不想等,會一直循環做這個操作,直到成功,如果CAS一直失敗的話,會對CPU帶來很大的開銷。

只能保證一個共享變量的原子操作​

當我們對一個共享的變量做操作的試試,我可通過CAS的方式保證是原子操作,,但是對多個共享變量操作是,循環的CAS就不能保證是原子操作了,因爲每個CAS只是一個變量,操作多個變量就是多個操作,就無法保證操作的原子性了,這時候就需要使用鎖來保障原子性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章