亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

AtomicInteger 原子類(lèi)的作用

MartinDai / 1334人閱讀

摘要:原子類(lèi)的作用多線程操作,性能開(kāi)銷(xiāo)太大并不是原子操作。每次比較的是兩個(gè)對(duì)象性能比要好使用時(shí),在高并發(fā)下大量線程會(huì)同時(shí)去競(jìng)爭(zhēng)更新同一個(gè)原子變量,但是由于同時(shí)只有一個(gè)線程的會(huì)成功,所以其他線程會(huì)不斷嘗試自旋嘗試操作,這會(huì)浪費(fèi)不少的資源。

AtomicInteger 原子類(lèi)的作用

多線程操作,Synchronized 性能開(kāi)銷(xiāo)太大count++不是原子操作。因?yàn)?b>count++需要經(jīng)過(guò)讀取-修改-寫(xiě)入三個(gè)步驟。

count++不是原子操作。因?yàn)?b>count++需要經(jīng)過(guò)讀取-修改-寫(xiě)入三個(gè)步驟。

可以這樣做:

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

Synchronized鎖是獨(dú)占的,意味著如果有別的線程在執(zhí)行,當(dāng)前線程只能是等待!

用CAS操作

CAS有3個(gè)操作數(shù):

內(nèi)存值V

舊的預(yù)期值A(chǔ)

要修改的新值B

當(dāng)多個(gè)線程嘗試使用CAS同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能更新變量的值(A和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B),而其它線程都失敗,失敗的線程并不會(huì)被掛起,而是被告知這次競(jìng)爭(zhēng)中失敗,并可以再次嘗試(或者什么都不做)

我們可以發(fā)現(xiàn)CAS有兩種情況:

如果內(nèi)存值V和我們的預(yù)期值A(chǔ)相等,則將內(nèi)存值修改為B,操作成功!

如果內(nèi)存值V和我們的預(yù)期值A(chǔ)不相等,一般也有兩種情況:

重試(自旋)

什么都不做

理解CAS的核心就是:

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

原子變量類(lèi)在java.util.concurrent.atomic包下,總體來(lái)看有這么多個(gè)

基本類(lèi)型:

AtomicBoolean:布爾型

AtomicInteger:整型

AtomicLong:長(zhǎng)整型

數(shù)組:

AtomicIntegerArray:數(shù)組里的整型

AtomicLongArray:數(shù)組里的長(zhǎng)整型

AtomicReferenceArray:數(shù)組里的引用類(lèi)型

引用類(lèi)型:

AtomicReference:引用類(lèi)型

AtomicStampedReference:帶有版本號(hào)的引用類(lèi)型

AtomicMarkableReference:帶有標(biāo)記位的引用類(lèi)型

對(duì)象的屬性

AtomicIntegerFieldUpdater:對(duì)象的屬性是整型

AtomicLongFieldUpdater:對(duì)象的屬性是長(zhǎng)整型

AtomicReferenceFieldUpdater:對(duì)象的屬性是引用類(lèi)型

JDK8新增DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder

是對(duì)AtomicLong等類(lèi)的改進(jìn)。比如LongAccumulator與LongAdder在高并發(fā)環(huán)境下比AtomicLong更高效。

Atomic包里的類(lèi)基本都是使用Unsafe實(shí)現(xiàn)的包裝類(lèi)

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

// 第一和第二個(gè)參數(shù)代表對(duì)象的實(shí)例以及地址,第三個(gè)參數(shù)代表期望值,第四個(gè)參數(shù)代表更新值
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);  

原子變量類(lèi)使用

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

原子類(lèi)的ABA問(wèn)題

下面的操作都可以正常執(zhí)行完的,這樣會(huì)發(fā)生什么問(wèn)題呢??線程C無(wú)法得知線程A和線程B修改過(guò)的count值,這樣是有風(fēng)險(xiǎn)的。

現(xiàn)在我有一個(gè)變量count=10,現(xiàn)在有三個(gè)線程,分別為A、B、C

線程A和線程C同時(shí)讀到count變量,所以線程A和線程C的內(nèi)存值和預(yù)期值都為10

此時(shí)線程A使用CAS將count值修改成100

修改完后,就在這時(shí),線程B進(jìn)來(lái)了,讀取得到count的值為100(內(nèi)存值和預(yù)期值都是100),將count值修改成10

線程C拿到執(zhí)行權(quán),發(fā)現(xiàn)內(nèi)存值是10,預(yù)期值也是10,將count值修改成11

解決ABA問(wèn)題

要解決ABA的問(wèn)題,我們可以使用JDK給我們提供的AtomicStampedReference和AtomicMarkableReference類(lèi)。

簡(jiǎn)單來(lái)說(shuō)就是在給為這個(gè)對(duì)象提供了一個(gè)版本,并且這個(gè)版本如果被修改了,是自動(dòng)更新的。

原理大概就是:維護(hù)了一個(gè)Pair對(duì)象,Pair對(duì)象存儲(chǔ)我們的對(duì)象引用和一個(gè)stamp值。每次CAS比較的是兩個(gè)Pair對(duì)象

LongAdder 性能比 AtomicLong 要好

使用AtomicLong時(shí),在高并發(fā)下大量線程會(huì)同時(shí)去競(jìng)爭(zhēng)更新同一個(gè)原子變量,但是由于同時(shí)只有一個(gè)線程的CAS會(huì)成功,所以其他線程會(huì)不斷嘗試自旋嘗試CAS操作,這會(huì)浪費(fèi)不少的CPU資源。

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

簡(jiǎn)單來(lái)說(shuō)就是將一個(gè)值分散成多個(gè)值,在并發(fā)的時(shí)候就可以分散壓力,性能有所提高。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/73487.html

相關(guān)文章

  • AtomicInteger原理

    摘要:提供這些原子類(lèi)的目的就是為了解決基本類(lèi)型操作的非原子性導(dǎo)致在多線程并發(fā)情況下引發(fā)的問(wèn)題。測(cè)試代碼引發(fā)的線程問(wèn)題最終的值為如果是原子操作,那么結(jié)果應(yīng)該就是,反復(fù)運(yùn)行幾次發(fā)現(xiàn)結(jié)果大部分情況下都不是,這也證明了的非原子性在多線程下產(chǎn)生的問(wèn)題。 AtomicInteger的原理 java的并發(fā)原子包里面提供了很多可以進(jìn)行原子操作的類(lèi),比如: AtomicInteger AtomicBoole...

    tuantuan 評(píng)論0 收藏0
  • Java多線程學(xué)習(xí)(九)JUC 中的 Atomic 原子類(lèi)總結(jié)

    摘要:即使是在多個(gè)線程一起執(zhí)行的時(shí)候,一個(gè)操作一旦開(kāi)始,就不會(huì)被其他線程干擾。另外是一個(gè)變量,在內(nèi)存中可見(jiàn),因此可以保證任何時(shí)刻任何線程總能拿到該變量的最新值。 個(gè)人覺(jué)得這一節(jié)掌握基本的使用即可! 本節(jié)思維導(dǎo)圖: showImg(https://segmentfault.com/img/remote/1460000016855442?w=1244&h=657); 1 Atomic 原子類(lèi)介紹...

    Youngs 評(píng)論0 收藏0
  • BATJ都愛(ài)問(wèn)的多線程面試題

    摘要:今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線程面試題,希望對(duì)大家學(xué)習(xí)和面試都能有所幫助。指令重排在單線程環(huán)境下不會(huì)出先問(wèn)題,但是在多線程環(huán)境下會(huì)導(dǎo)致一個(gè)線程獲得還沒(méi)有初始化的實(shí)例。使用可以禁止的指令重排,保證在多線程環(huán)境下也能正常運(yùn)行。 下面最近發(fā)的一些并發(fā)編程的文章匯總,通過(guò)閱讀這些文章大家再看大廠面試中的并發(fā)編程問(wèn)題就沒(méi)有那么頭疼了。今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線...

    高勝山 評(píng)論0 收藏0
  • Java多線程進(jìn)階(十三)—— J.U.C之a(chǎn)tomic框架:AtomicInteger

    摘要:顧名思義,是類(lèi)型的線程安全原子類(lèi),可以在應(yīng)用程序中以原子的方式更新值。創(chuàng)建對(duì)象先來(lái)看下對(duì)象的創(chuàng)建。也就是說(shuō)當(dāng)一個(gè)線程修改一個(gè)共享變量時(shí),其它線程能立即讀到這個(gè)修改的值。 showImg(https://segmentfault.com/img/remote/1460000016012210); 本文首發(fā)于一世流云的專(zhuān)欄:https://segmentfault.com/blog... ...

    darkbug 評(píng)論0 收藏0
  • java 關(guān)鍵字總結(jié)

    摘要:關(guān)鍵字總結(jié)有個(gè)關(guān)鍵字,它們是接下來(lái)對(duì)其中常用的幾個(gè)關(guān)鍵字進(jìn)行概括。而通過(guò)關(guān)鍵字,并不能解決非原子操作的線程安全性。為了在一個(gè)特定對(duì)象的一個(gè)域上關(guān)閉,可以在這個(gè)域前加上關(guān)鍵字。是語(yǔ)言的關(guān)鍵字,用來(lái)表示一個(gè)域不是該對(duì)象串行化的一部分。 java 關(guān)鍵字總結(jié) Java有50個(gè)關(guān)鍵字,它們是: abstract do implements private ...

    honmaple 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<