中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

AtomicInteger原子類的作用是什么

發布時間:2020-10-15 19:32:10 來源:億速云 閱讀:366 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關AtomicInteger原子類的作用是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

AtomicInteger 原子類的作用

多線程操作,Synchronized 性能開銷太大count++并不是原子操作。因為count++需要經過讀取-修改-寫入三個步驟。

count++并不是原子操作。因為count++需要經過讀取-修改-寫入三個步驟。

可以這樣做:

public synchronized void increase() {
    count++;
}

Synchronized鎖是獨占的,意味著如果有別的線程在執行,當前線程只能是等待!

用CAS操作

CAS有3個操作數:

內存值V舊的預期值A要修改的新值B當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值(A和內存值V相同時,將內存值V修改為B),而其它線程都失敗,失敗的線程并不會被掛起,而是被告知這次競爭中失敗,并可以再次嘗試(或者什么都不做)。

我們可以發現CAS有兩種情況:

如果內存值V和我們的預期值A相等,則將內存值修改為B,操作成功!

如果內存值V和我們的預期值A不相等,一般也有兩種情況:

重試(自旋)什么都不做

理解CAS的核心就是:

CAS是原子性的,雖然你可能看到比較后再修改(compare and swap)覺得會有兩個操作,但終究是原子性的!

原子變量類在java.util.concurrent.atomic包下,總體來看有這么多個

基本類型:

AtomicBoolean:布爾型AtomicInteger:整型AtomicLong:長整型

數組:

AtomicIntegerArray:數組里的整型AtomicLongArray:數組里的長整型AtomicReferenceArray:數組里的引用類型

引用類型:

AtomicReference:引用類型AtomicStampedReference:帶有版本號的引用類型AtomicMarkableReference:帶有標記位的引用類型

對象的屬性

AtomicIntegerFieldUpdater:對象的屬性是整型AtomicLongFieldUpdater:對象的屬性是長整型AtomicReferenceFieldUpdater:對象的屬性是引用類型

JDK8新增DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder

是對AtomicLong等類的改進。比如LongAccumulator與LongAdder在高并發環境下比AtomicLong更高效。Atomic包里的類基本都是使用Unsafe實現的包裝類

Unsafe里邊有幾個我們喜歡的方法(CAS):

// 第一和第二個參數代表對象的實例以及地址,第三個參數代表期望值,第四個參數代表更新值
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

原子變量類使用

class Count{
    // 共享變量(使用AtomicInteger來替代Synchronized鎖)
    private AtomicInteger count = new AtomicInteger(0);
    public Integer getCount() {
        return count.get();
    }
    public void increase() {
        count.incrementAndGet();
    }
}

原子類的ABA問題

下面的操作都可以正常執行完的,這樣會發生什么問題呢??線程C無法得知線程A和線程B修改過的count值,這樣是有風險的。

現在我有一個變量count=10,現在有三個線程,分別為A、B、C線程A和線程C同時讀到count變量,所以線程A和線程C的內存值和預期值都為10此時線程A使用CAS將count值修改成100修改完后,就在這時,線程B進來了,讀取得到count的值為100(內存值和預期值都是100),將count值修改成10線程C拿到執行權,發現內存值是10,預期值也是10,將count值修改成11

解決ABA問題

要解決ABA的問題,我們可以使用JDK給我們提供的AtomicStampedReference和AtomicMarkableReference類。

簡單來說就是在給為這個對象提供了一個版本,并且這個版本如果被修改了,是自動更新的。

原理大概就是:維護了一個Pair對象,Pair對象存儲我們的對象引用和一個stamp值。每次CAS比較的是兩個Pair對象

LongAdder 性能比 AtomicLong 要好

使用AtomicLong時,在高并發下大量線程會同時去競爭更新同一個原子變量,但是由于同時只有一個線程的CAS會成功,所以其他線程會不斷嘗試自旋嘗試CAS操作,這會浪費不少的CPU資源。

而LongAdder可以概括成這樣:內部核心數據value分離成一個數組(Cell),每個線程訪問時,通過哈希等算法映射到其中一個數字進行計數,而最終的計數結果,則為這個數組的求和累加。

簡單來說就是將一個值分散成多個值,在并發的時候就可以分散壓力,性能有所提高。

關于AtomicInteger原子類的作用是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

繁峙县| 惠来县| 吴江市| 枣强县| 邯郸市| 唐河县| 阳东县| 察雅县| 无极县| 信丰县| 昌都县| 越西县| 黄平县| 延川县| 达孜县| 吉隆县| 大足县| 西华县| 望江县| 西丰县| 静海县| 平塘县| 义马市| 高邑县| 轮台县| 许昌市| 南投县| 黄大仙区| 丹棱县| 金寨县| 板桥市| 台州市| 尉犁县| 柏乡县| 东源县| 元朗区| 灯塔市| 沈丘县| 岚皋县| 西安市| 白朗县|