多線程(七):AtomicInteger

包括:
一. AtomicInteger 概念,API
二. CAS 算法簡介


一. AtomicInteger 概念,API
       我們知道,i++ 操作並不是原子性的,多線程下使用 可能會出現問題。那麼AtomicInteger 就可以解決這個問題,利用 AtomicInteger,一個變量的自增可以是原子性的。當然,我們也可以通過 lock 或者 synchronized 等方法正常 使用 i ++。

常用API:

public class AtomicIntegerTest {
	public static void main(String[] args) {
		AtomicInteger a = new AtomicInteger();
		a.incrementAndGet(); //++i
		a.getAndIncrement(); //i++
		a.decrementAndGet(); //--i
		a.getAndDecrement(); //i--
	}
}

二. CAS 算法簡介
        AtomicInteger 實現原理:主要通過 CAS 算法。也就是說,對某個內存值拷貝一個副本,某個線程若讀到該副本,並對其進行計算,輸出結果,在寫入內存時,再次取出內存值和該副本比較,若副本和內存值相同,則把新的值寫入內存。
        CAS 算法儘可能的縮小了鎖的範圍,所有速度效率上會比 Lock,Synchronized 高很多。現代的CPU提供了特殊的指令,可以自動更新共享數據,而且能夠檢測到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定。
        CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改爲B,否則什麼都不做。例如一個 ++i 算法:
public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

        在這裏採用了CAS操作,每次從內存中讀取數據然後將此數據和+1後的結果進行CAS操作,如果成功就返回結果,否則重試直到成功爲止。而compareAndSet利用JNI來完成CPU指令的操作。

缺點:
  1. ABA問題
  2. 循環時間長開銷大。自旋CAS如果長時間不成功,會給CPU帶來非常大的執行開銷。
  3. 只能保證一個共享變量的原子操作。當對一個共享變量執行操作時,我們可以使用循環CAS的方式來保證原子 操作,但是對多個共享變量操作時,循環CAS就無法保證操作的原子性,這個時候就可以用鎖,或者有一個取巧的辦法,就是把多個共享變量合併成一個共享變量 來操作。比如有兩個共享變量i=2,j=a,合併一下ij=2a,然後用CAS來操作ij。從Java1.5開始JDK提供了AtomicReference類來保證引用對象之間的原子性,你可以把多個變量放在一個對象裏來進行CAS操作。
PS:
  1. ABA 問題: AtomicInteger 可能出現ABA問題,也就是若其中一個線程修改A->B->A,另外一個線程仍然讀取到A,雖然值是預期值,但並不能說明該內存值沒有變化。ABA問題的解決方案:通過標記或者版本號和每一個CAS操作的值相綁定,並且原子性的更新值和標記來處理這類問題。從Java1.5開始JDK的atomic包裏提供了一個類AtomicStampedReference來解決 ABA問題。這個類的compareAndSet方法作用是首先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如果全部相等,則以原子方 式將該引用和該標誌的值設置爲給定的更新值。
  2. 樂觀鎖 和 悲觀鎖:獨佔鎖是一種悲觀鎖,synchronized就是一種獨佔鎖,會導致其它所有需要鎖的線程掛起,等待持有鎖的線程釋放鎖。而另一個更加有效的鎖就是樂觀鎖。所謂樂觀鎖就是,每次不加鎖而是假設沒有衝突而去完成某項操作,如果因爲衝突失敗就重試,直到成功爲止。java.util.concurrent包中藉助CAS實現了區別於synchronized悲觀鎖的一種樂觀鎖。


參考:
  1. AtomicInteger原理:http://caogen81.iteye.com/blog/2002884
  2. 理解 CAS算法在Java 中的作用:http://www.cnblogs.com/onlywujun/articles/3529572.html


發佈了97 篇原創文章 · 獲贊 19 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章