成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

CAS 算法 —— Compare and Swap

mmy123456 / 1507人閱讀

摘要:算法算法會(huì)先對(duì)一個(gè)內(nèi)存變量位置和一個(gè)給定的值進(jìn)行比較,如果相等,則用一個(gè)新值去修改這個(gè)內(nèi)存變量位置。因?yàn)槭欠枪芥i,所以一上來(lái)就嘗試搶占鎖給定舊值并希望用新值去更新內(nèi)存變量。

本文翻譯和原創(chuàng)各占一半,所以還是厚顏無(wú)恥歸類(lèi)到原創(chuàng)好了...
https://howtodoinjava.com/jav...
java 5 其中一個(gè)令人振奮的改進(jìn)是新增了支持原子操作的類(lèi)型,例如 AtomicInteger, AtomicLong 等。在多線程環(huán)境中進(jìn)行簡(jiǎn)單的自增自減操作時(shí),這些原子類(lèi)能幫助你減少很多用于多線程同步的復(fù)雜代碼。這些原子類(lèi)依賴(lài)于 CAS (compare and swap) 算法,接下來(lái)我們會(huì)討論 CAS 這個(gè)概念。

樂(lè)觀鎖和悲觀鎖

傳統(tǒng)的鎖機(jī)制,例如 java 的 synchronized 關(guān)鍵字,他代表了 java 中悲觀鎖技術(shù),保證了某一時(shí)刻僅有一個(gè)線程能訪問(wèn)同步代碼/方法。synchronized 能夠很好地工作,卻有著 (相對(duì)) 比較大的性能開(kāi)銷(xiāo)。
樂(lè)觀鎖 (相對(duì)悲觀鎖) 對(duì)性能會(huì)有很大的幫助。他的核心思想是:你寄希望于在沒(méi)有沖突的情況下完成一次更新操作,使用樂(lè)觀鎖技術(shù)更新時(shí)會(huì)進(jìn)行 “沖突檢測(cè)” 來(lái)判斷是否有其他的線程干擾,若是 (有其他線程干擾) 則視本次更新操作失敗,一般會(huì)進(jìn)行重試 (可以了解一下CAS自旋)。Compare and Swap 就是典型的樂(lè)觀鎖技術(shù)。

CAS 算法

CAS 算法會(huì)先對(duì)一個(gè)內(nèi)存變量(位置) V 和一個(gè)給定的值進(jìn)行比較 A ,如果相等,則用一個(gè)新值 B 去修改這個(gè)內(nèi)存變量(位置)。上述過(guò)程會(huì)作為一個(gè)原子操作完成 (intel處理器通過(guò) cmpxchg 指令系列實(shí)現(xiàn))。CAS 原子性保證了新值的計(jì)算是基于上一個(gè)有效值,期間如果內(nèi)存變量(位置) V 被其他線程更新了,本線程的 CAS 更新操作將會(huì)失敗。CAS 操作必須告訴調(diào)用者成功與否,可以返回一個(gè) boolean 值來(lái)表示,或者返回一個(gè)從內(nèi)存變量讀到的值 (應(yīng)該是上一次有效值)

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

內(nèi)存變量(位置) V,表示被更新的變量

線程上一次讀到的舊值 A

用來(lái)覆蓋 V 的新值 B

CAS 表示:“我認(rèn)為現(xiàn)在 V 的值還是之前我讀到的舊值 A,若是則用新值 B 覆蓋內(nèi)存變量 V,否則不做任何動(dòng)作并告訴調(diào)用者操作失敗”。CAS 是一項(xiàng)樂(lè)觀鎖技術(shù),他在更新的時(shí)候總是希望能成功 (沒(méi)有沖突),但也能檢測(cè)出來(lái)自其他線程的沖突和干擾
Java 中的 Compare and Swap

這里我們關(guān)注一下ReentrantLock鎖定和解鎖那部分的源碼

//ReentrantLock.lock()
public void lock() {
    sync.lock();
}

他依賴(lài)了其內(nèi)部類(lèi)Synclock(),以下是內(nèi)部類(lèi) Sync (繼承了隊(duì)列同步器 AQS)

abstract static class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = -5179523762034025860L;

    abstract void lock();
    ................

Sync還是個(gè)抽象類(lèi),一般 new ReentrantLock() 時(shí)創(chuàng)建的是 NonfairSync

// ReentrantLock的構(gòu)造方法
public ReentrantLock() {
    sync = new NonfairSync();
}

下面就是NonfairSynclock() 方法了

final void lock() {
    if (compareAndSetState(0, 1)) // 1
        setExclusiveOwnerThread(Thread.currentThread()); // 2
    else
        acquire(1); // 3
}

1 中的 compareAndSetState() 承繼自隊(duì)列同步器 AQS,封裝了 CAS 指令。因?yàn)槭?NonfairSync 非公平鎖,所以一上來(lái)就嘗試搶占鎖:給定舊值 0 并希望用新值 1 去更新內(nèi)存變量 State。若更新成功則視為獲取鎖成功,并執(zhí)行 2

2 成功完成了 CAS 操作 (沒(méi)錯(cuò),當(dāng)你使用 CAS 指令成功把 State 從 0 更新成 1 便視為獲取鎖,就是這么簡(jiǎn)單粗暴 ╮(╯▽╰)╭ ),把當(dāng)前線程設(shè)為獨(dú)占線程

3 操作失敗 (被人搶先獲取鎖(╯`□′)╯╧╧),進(jìn)行 acquire 操作再次嘗試獲取鎖,若還是不行,則把當(dāng)前線程加入 AQS 等待隊(duì)列,由 AQS 來(lái)管理隊(duì)列中等待線程的阻塞和喚醒,具體代碼就不貼出來(lái)了,AQS 的源碼多處使用到 CAS 指令,有興趣的同學(xué)可以查看

鎖用完了要釋放,下面貼出 unlock() 方法

// ReentrantLock.unlock()
public void unlock() {
    sync.release(1);
}

這里還是依賴(lài)了 sync,release() 是 AQS 的通用方法,其內(nèi)部調(diào)用了 tryRelease() (由 Sync 類(lèi)實(shí)現(xiàn)),這里直接貼出 Sync 的 tryRelease()

protected final boolean tryRelease(int releases) { // releases 參數(shù)的值是上面?zhèn)鬟M(jìn)來(lái)的 1
    int c = getState() - releases; // 1
    if (Thread.currentThread() != getExclusiveOwnerThread()) // 1.5
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) { // 2
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c); // 3
    return free;
}

1 處的c 是內(nèi)存變量 State 即將要被更新的值,因?yàn)?ReentrantLock 是可重入鎖 (當(dāng)前線程可多次獲取鎖),所以 State 的值是可以大于 1 的。

2 判斷若新值為 0,則視為鎖被釋放并設(shè)置當(dāng)前獨(dú)占線程為 null

3 把 State 的值更新為 c,思考一下這里的更新操作為什么沒(méi)用到 CAS 指令?

1.5 解釋了上面的疑問(wèn),只有當(dāng)前獨(dú)占線程有能力對(duì) State 變量進(jìn)行修改,不需要進(jìn)行同步或使用 CAS

Summary

AQS 隊(duì)列同步器以及 java.util.concurrent 下各種鎖和原子類(lèi)都運(yùn)用到的 CAS 算法,有時(shí)間的同學(xué)建議閱讀加深印象。

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

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

相關(guān)文章

  • 貓頭鷹的深夜翻譯:Java中的CAS(Compare And Swap)

    摘要:否則它就會(huì)用新的值替代當(dāng)前值。在這種情況下,鎖可能會(huì)優(yōu)于原子變量,但在實(shí)際的爭(zhēng)用級(jí)別中,原子變量的性能優(yōu)于鎖。在中引入了另外一個(gè)構(gòu)件。 題目要求 在我們深入了解CAS(Compare And Swap)策略以及它是如何在AtomicInteger這樣的原子構(gòu)造器中使用的,首先來(lái)看一下這段代碼: public class MyApp { private volatile int ...

    hosition 評(píng)論0 收藏0
  • java 鎖機(jī)制

    摘要:在包中已經(jīng)包含了讀寫(xiě)鎖樂(lè)觀鎖總是認(rèn)為不會(huì)產(chǎn)生并發(fā)問(wèn)題,每次去取數(shù)據(jù)的時(shí)候總認(rèn)為不會(huì)有其他線程對(duì)數(shù)據(jù)進(jìn)行修改,因此不會(huì)上鎖,但是在更新時(shí)會(huì)判斷其他線程在這之前有沒(méi)有對(duì)數(shù)據(jù)進(jìn)行修改,一般會(huì)使用版本號(hào)機(jī)制或操作實(shí)現(xiàn)。 重入鎖 鎖作為并發(fā)共享數(shù)據(jù),保證一致性的工具,在JAVA平臺(tái)有多種實(shí)現(xiàn)(如 synchronized(重量級(jí)) 和 ReentrantLock(輕量級(jí))等等 ) 。這些已經(jīng)寫(xiě)好...

    wfc_666 評(píng)論0 收藏0
  • CAS

    摘要:與同步方式在多線程情況下,可以采用同步阻塞悲觀鎖或樂(lè)觀鎖的方式實(shí)現(xiàn)業(yè)務(wù),具體要看業(yè)務(wù)場(chǎng)景,如果重試的代價(jià)很小,那用是合適的,但如果每次重試都需要花費(fèi)大量的時(shí)間或資源,那應(yīng)該采用同步方式。 CAS介紹 CAS - Compare And Swap (Compare And Set, Check And Set) wikipedia的描述如下: 比較并交換(compare and swap...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<