JUC下的AtomicInteger——CAS

一、簡介

JUC下的atomic包,提供了一系列原子操作的包裝類。利用此包下的類,可以實現常見如i++的原子操作。包下的類如下:

二、AtomicInteger

其中AtomicInteger是一個常用的類,可以實現自增或者增加任意數的原子操作。其中實現的關鍵方式是使用UnSafe類以及CAS思想。以下爲AtomicInteger的類:

而AtomicInteger的自增方法getAndIncrement,通過調用UnSafe類的getAndAddInt()來實現。

三、CAS介紹

CAS(compare and swap),也就是比較並交換。概括而言就是如果內存值==預期值,則內存值=更新值。

首先,CAS是樂觀鎖的一種實現方式,他採用的是自旋鎖的思想,是一種輕量級的鎖機制。即每次判斷我的預期值和內存中的值是不是相同,如果不相同則說明該內存值已經被其他線程更新過了,因此需要拿到該最新值作爲預期值,重新判斷。而該線程不斷的循環判斷是否該內存值已經被其他線程更新過了,這就是自旋的思想。

在UnSafe類中,使用的就是自旋鎖的方式實現原子操作。

四、CAS的缺點

CAS使用自旋鎖的方式,由於該鎖會不斷循環判斷,因此不會類似synchronize線程阻塞導致線程切換。但是不斷的自旋,會導致CPU的消耗,在併發量大的時候容易導致CPU跑滿。

其次,是CAS存在ABA問題。

五、ABA問題

ABA問題,即某個線程將內存值由A改爲了B,再由B改爲了A。當另外一個線程使用預期值去判斷時,預期值與內存值相同,誤以爲該變量沒有被修改過而導致的問題。

解決ABA問題的主要方式,通過使用類似添加版本號的方式,來避免ABA問題。如原先的內存值爲(A,1),線程將(A,1)修改爲了(B,2),再由(B,2)修改爲(A,3)。此時另一個線程使用預期值(A,1)與內存值(A,3)進行比較,只需要比較版本號1和3,即可發現該內存中的數據被更新過了。

 

 

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