成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

CAS 算法 —— Compare and Swap

mmy123456 / 1649人閱讀

摘要:算法算法會先對一個內(nèi)存變量位置和一個給定的值進行比較,如果相等,則用一個新值去修改這個內(nèi)存變量位置。因為是非公平鎖,所以一上來就嘗試搶占鎖給定舊值并希望用新值去更新內(nèi)存變量。

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

樂觀鎖和悲觀鎖

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

CAS 算法

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

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

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

線程上一次讀到的舊值 A

用來覆蓋 V 的新值 B

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

這里我們關注一下ReentrantLock鎖定和解鎖那部分的源碼

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

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

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

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

Sync還是個抽象類,一般 new ReentrantLock() 時創(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() 承繼自隊列同步器 AQS,封裝了 CAS 指令。因為是 NonfairSync 非公平鎖,所以一上來就嘗試搶占鎖:給定舊值 0 并希望用新值 1 去更新內(nèi)存變量 State。若更新成功則視為獲取鎖成功,并執(zhí)行 2

2 成功完成了 CAS 操作 (沒錯,當你使用 CAS 指令成功把 State 從 0 更新成 1 便視為獲取鎖,就是這么簡單粗暴 ╮(╯▽╰)╭ ),把當前線程設為獨占線程

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

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

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

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

protected final boolean tryRelease(int releases) { // releases 參數(shù)的值是上面?zhèn)鬟M來的 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 即將要被更新的值,因為 ReentrantLock 是可重入鎖 (當前線程可多次獲取鎖),所以 State 的值是可以大于 1 的。

2 判斷若新值為 0,則視為鎖被釋放并設置當前獨占線程為 null

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

1.5 解釋了上面的疑問,只有當前獨占線程有能力對 State 變量進行修改,不需要進行同步或使用 CAS

Summary

AQS 隊列同步器以及 java.util.concurrent 下各種鎖和原子類都運用到的 CAS 算法,有時間的同學建議閱讀加深印象。

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/73081.html

相關文章

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

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

    hosition 評論0 收藏0
  • java 鎖機制

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

    wfc_666 評論0 收藏0
  • CAS

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

    joy968 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<