精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

并發(fā)樂觀鎖CAS原理,吊打問并發(fā)的面試官

開發(fā) 前端
synchronized 在 jdk1.6 之后,已經(jīng)改進(jìn)優(yōu)化。synchronized 的底層實(shí)現(xiàn)主要依靠 Lock-Free 的隊(duì)列,基本思路是自旋后阻塞,競(jìng)爭(zhēng)切換后繼續(xù)競(jìng)爭(zhēng)鎖,稍微犧牲了公平性,但獲得了高吞吐量。在線程沖突較少的情況下,可以獲得和 CAS 類似的性能;而線程沖突嚴(yán)重的情況下,性能遠(yuǎn)高于 CAS。

CAS的英文為Compare and Swap 翻譯為比較并交換。

CASvolatile關(guān)鍵字是實(shí)現(xiàn)并發(fā)包的基石。沒有CAS就不會(huì)有并發(fā)包,synchronized是一種獨(dú)占鎖、悲觀鎖,java.util.concurrent中借助了CAS指令實(shí)現(xiàn)了一種區(qū)別于synchronized的一種樂觀鎖。

一、什么是樂觀鎖與悲觀鎖?

樂觀鎖和悲觀鎖是一種概念和思想:

悲觀鎖:總是假設(shè)最壞的情況,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣當(dāng)?shù)诙€(gè)線程想拿這個(gè)數(shù)據(jù)的時(shí)候,第二個(gè)線程會(huì)一直堵塞,直到第一個(gè)釋放鎖,他拿到鎖后才可以訪問。傳統(tǒng)的數(shù)據(jù)庫(kù)里面就用到了這種鎖機(jī)制,例如:行鎖,表鎖,讀鎖,寫鎖,都是在操作前先上鎖。java中的synchronized的實(shí)現(xiàn)也是一種悲觀鎖。

樂觀鎖:樂觀鎖概念為,每次拿數(shù)據(jù)的時(shí)候都認(rèn)為別的線程不會(huì)修改這個(gè)數(shù)據(jù),所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別的線程有沒有修改過數(shù)據(jù),樂觀鎖適用于讀操作多的場(chǎng)景,這樣可以提高程序的吞吐量。在Java中
java.util.concurrent.atomic包下面的原子變量就是使用了樂觀鎖的一種實(shí)現(xiàn)方式CAS實(shí)現(xiàn)。

二、背景:

在JDK 5之前Java語(yǔ)言是靠 synchronized 關(guān)鍵字保證同步的,這會(huì)導(dǎo)致有鎖。鎖機(jī)制存在以下問題:

  • 在多線程競(jìng)爭(zhēng)下,加鎖、釋放鎖會(huì)導(dǎo)致比較多的上下文切換和調(diào)度延時(shí),引起性能問題。
  • 一個(gè)線程持有鎖會(huì)導(dǎo)致其它所有需要此鎖的線程掛起。
  • 如果一個(gè)優(yōu)先級(jí)高的線程等待一個(gè)優(yōu)先級(jí)低的線程釋放鎖會(huì)導(dǎo)致優(yōu)先級(jí)倒置,引起性能風(fēng)險(xiǎn)。

Volatile關(guān)鍵字能夠在并發(fā)條件下,強(qiáng)制將修改后的值刷新到主內(nèi)存中來保持內(nèi)存的可見性。通過 CPU內(nèi)存屏障禁止編譯器指令性重排來保證并發(fā)操作的有序性

如果多個(gè)線程同時(shí)操作 Volatile 修飾的變量,也會(huì)造成數(shù)據(jù)的不一致。

public class Test {
    public volatile int inc = 0;
     
    public void increase() {
        inc++;
    }     
    public static void main(String[] args) {
        final Test test = new Test();
        for(int i=0;i<10;i++){
            new Thread(){
                public void run() {
                    for(int j=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }    
        while(Thread.activeCount()>1)
            Thread.yield();
        System.out.println(test.inc);
    }
}

事實(shí)上運(yùn)行它會(huì)發(fā)現(xiàn)每次運(yùn)行結(jié)果都不一致,都是一個(gè)小于10000的數(shù)字。

假如某個(gè)時(shí)刻變量 inc 的值為10:

  • 線程1對(duì)變量進(jìn)行自增操作,線程1先讀取了變量inc的原始值,然后線程1被阻塞了;
  • 然后線程2對(duì)變量進(jìn)行自增操作,線程2也去讀取變量inc的原始值,由于線程1只是對(duì)變量inc進(jìn)行讀取操作,而沒有對(duì)變量進(jìn)行修改操作,所以不會(huì)導(dǎo)致線程2的工作內(nèi)存中緩存變量inc的緩存行無(wú)效,所以線程2會(huì)直接去主存讀取inc的值,發(fā)現(xiàn)inc的值時(shí)10,然后進(jìn)行加1操作,并把11寫入工作內(nèi)存,最后寫入主存。
  • 然后線程1接著進(jìn)行加1操作,由于已經(jīng)讀取了inc的值,注意此時(shí)在線程1的工作內(nèi)存中inc的值仍然為10,所以線程1對(duì)inc進(jìn)行加1操作后inc的值為11,然后將11寫入工作內(nèi)存,最后寫入主存。
  • 那么兩個(gè)線程分別進(jìn)行了一次自增操作后,inc只增加了1。

之所以出現(xiàn)還是 volatile 只是保證讀寫具有原子性,但是對(duì)于 ++ 操作的復(fù)合操作是不存在原子操作的。只能在有限的一些情形下使用 volatile 變量替代鎖。要使 volatile 變量提供理想的線程安全,比如:對(duì)變量的寫操作不依賴于當(dāng)前值。

volatile 是不錯(cuò)的機(jī)制,但是 volatile 不能保證原子性。因此對(duì)于同步最終還是要回到鎖機(jī)制上來。

獨(dú)占鎖是一種悲觀鎖,synchronized 就是一種獨(dú)占鎖,會(huì)導(dǎo)致其它所有需要鎖的線程掛起,等待持有鎖的線程釋放鎖。而另一個(gè)更加有效的鎖就是樂觀鎖。所謂樂觀鎖就是,每次不加鎖而是假設(shè)沒有沖突而去完成某項(xiàng)操作,如果因?yàn)闆_突失敗就重試,直到成功為止。樂觀鎖用到的機(jī)制就是 CAS。

三、CAS原理:

CAS 操作包含三個(gè)操作數(shù) -- 內(nèi)存位置、預(yù)期數(shù)值和新值。CAS 的實(shí)現(xiàn)邏輯是將內(nèi)存位置處的數(shù)值與預(yù)期數(shù)值想比較,若相等,則將內(nèi)存位置處的值替換為新值。若不相等,則不做任何操作。

在 Java 中,Java 并沒有直接實(shí)現(xiàn) CAS,CAS 相關(guān)的實(shí)現(xiàn)是通過 C++ 內(nèi)聯(lián)匯編的形式實(shí)現(xiàn)的。Java 代碼需通過 JNI 才能調(diào)用。

在JVM中的CAS操作就是基于處理器的CMPXCHG匯編指令實(shí)現(xiàn)的,因此,JVM中的CAS的原子性是處理器保障的

CAS 是一條 CPU 的原子指令(cmpxchg指令),不會(huì)造成所謂的數(shù)據(jù)不一致問題,Unsafe 提供的 CAS 方法(如compareAndSwapXXX)底層實(shí)現(xiàn)即為 CPU 指令 cmpxchg

對(duì)
java.util.concurrent.atomic 包下的原子類 AtomicInteger 中的 compareAndSet 方法進(jìn)行分析,相關(guān)分析如下:

public class AtomicInteger extends Number implements java.io.Serializable {    
    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();    
    private static final long valueOffset;   
    static {       
        try {            
            // 計(jì)算變量 value 在類對(duì)象中的偏移
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }        private volatile int value;    
    public final boolean compareAndSet(int expect, int update) {                /**
         * compareAndSet 實(shí)際上只是一個(gè)殼子,主要的邏輯封裝在 Unsafe 的 
         * compareAndSwapInt 方法中
         */
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }    
    // ......
}
  public final class Unsafe {    
      // compareAndSwapInt 是 native 類型的方法,繼續(xù)往下看
      public final native boolean compareAndSwapInt(Object o, long offset,  int expected,  int x);    
      // ......
  }
public class AtomicInteger extends Number implements java.io.Serializable {    
    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();    
    private static final long valueOffset;   
    static {       
        try {            
            // 計(jì)算變量 value 在類對(duì)象中的偏移
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }        private volatile int value;    
    public final boolean compareAndSet(int expect, int update) {                /**
         * compareAndSet 實(shí)際上只是一個(gè)殼子,主要的邏輯封裝在 Unsafe 的 
         * compareAndSwapInt 方法中
         */
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }    
    // ......
}
  public final class Unsafe {    
      // compareAndSwapInt 是 native 類型的方法,繼續(xù)往下看
      public final native boolean compareAndSwapInt(Object o, long offset,  int expected,  int x);    
      // ......
  }

上面的分析看起來比較多,不過主流程并不復(fù)雜。如果不糾結(jié)于代碼細(xì)節(jié),還是比較容易看懂的。接下來,我會(huì)分析 Windows 平臺(tái)下的 Atomic::cmpxchg 函數(shù)。繼續(xù)往下看吧。

// atomic_windows_x86.inline.hpp
#define LOCK_IF_MP(mp) __asm cmp mp, 0  \
                       __asm je L0      \
                       __asm _emit 0xF0 \
                       __asm L0:
              inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {  // alternative for InterlockedCompareExchange
  int mp = os::is_MP();
  __asm {
    mov edx, dest
    mov ecx, exchange_value
    mov eax, compare_value    LOCK_IF_MP(mp)
    cmpxchg dword ptr [edx], ecx
  }
}

上面的代碼由 LOCK_IF_MP 預(yù)編譯標(biāo)識(shí)符和 cmpxchg 函數(shù)組成。為了看到更清楚一些,我們將 cmpxchg 函數(shù)中的 LOCK_IF_MP 替換為實(shí)際內(nèi)容。如下:

inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {  
  // 判斷是否是多核 CPU
  int mp = os::is_MP();
  __asm {    // 將參數(shù)值放入寄存器中
    mov edx, dest    // 注意: dest 是指針類型,這里是把內(nèi)存地址存入 edx 寄存器中
    mov ecx, exchange_value
    mov eax, compare_value    
    // LOCK_IF_MP
    cmp mp, 0
    /*
     * 如果 mp = 0,表明是線程運(yùn)行在單核 CPU 環(huán)境下。此時(shí) je 會(huì)跳轉(zhuǎn)到 L0 標(biāo)記處,
     * 也就是越過 _emit 0xF0 指令,直接執(zhí)行 cmpxchg 指令。也就是不在下面的 cmpxchg 指令
     * 前加 lock 前綴。
     */
    je L0    /*
     * 0xF0 是 lock 前綴的機(jī)器碼,這里沒有使用 lock,而是直接使用了機(jī)器碼的形式。至于這樣做的
     * 原因可以參考知乎的一個(gè)回答:
     *     https://www.zhihu.com/question/50878124/answer/123099923
     */ 
    _emit 0xF0L0:    /*
     * 比較并交換。簡(jiǎn)單解釋一下下面這條指令,熟悉匯編的朋友可以略過下面的解釋:
     *   cmpxchg: 即“比較并交換”指令
     *   dword: 全稱是 double word,在 x86/x64 體系中,一個(gè) 
     *          word = 2 byte,dword = 4 byte = 32 bit
     *   ptr: 全稱是 pointer,與前面的 dword 連起來使用,表明訪問的內(nèi)存單元是一個(gè)雙字單元
     *   [edx]: [...] 表示一個(gè)內(nèi)存單元,edx 是寄存器,dest 指針值存放在 edx 中。
     *          那么 [edx] 表示內(nèi)存地址為 dest 的內(nèi)存單元
     *          
     * 這一條指令的意思就是,將 eax 寄存器中的值(compare_value)與 [edx] 雙字內(nèi)存單元中的值
     * 進(jìn)行對(duì)比,如果相同,則將 ecx 寄存器中的值(exchange_value)存入 [edx] 內(nèi)存單元中。
     */
    cmpxchg dword ptr [edx], ecx
  }
}

到這里 CAS 的實(shí)現(xiàn)過程就講完了,CAS 的實(shí)現(xiàn)離不開處理器的支持。如上面源代碼所示,程序會(huì)根據(jù)當(dāng)前處理器的類型來決定是否為 cmpxchg 指令添加 lock 前綴。如果程序是在多處理器上運(yùn)行,就為 cmpxchg 指令加上 lock 前綴(lock cmpxchg)。反之,如果程序是在單處理器上運(yùn)行,就省略 lock 前綴(單處理器自身會(huì)維護(hù)單處理器內(nèi)的順序一致性,不需要 lock 前綴提供的內(nèi)存屏障效果)。

intel 的手冊(cè)對(duì) lock 前綴的說明如下:

  • 確保對(duì)內(nèi)存的讀 - 改 - 寫操作原子執(zhí)行。在 Pentium 及 Pentium 之前的處理器中,帶有 lock 前綴的指令在執(zhí)行期間會(huì)鎖住總線,使得其他處理器暫時(shí)無(wú)法通過總線訪問內(nèi)存。很顯然,這會(huì)帶來昂貴的開銷。從 Pentium 4,Intel Xeon 及 P6 處理器開始,intel 在原有總線鎖的基礎(chǔ)上做了一個(gè)很有意義的優(yōu)化:如果要訪問的內(nèi)存區(qū)域(area of memory)在 lock 前綴指令執(zhí)行期間已經(jīng)在處理器內(nèi)部的緩存中被鎖定(即包含該內(nèi)存區(qū)域的緩存行當(dāng)前處于獨(dú)占或以修改狀態(tài)),并且該內(nèi)存區(qū)域被完全包含在單個(gè)緩存行(cache line)中,那么處理器將直接執(zhí)行該指令。由于在指令執(zhí)行期間該緩存行會(huì)一直被鎖定,其它處理器無(wú)法讀 / 寫該指令要訪問的內(nèi)存區(qū)域,因此能保證指令執(zhí)行的原子性。這個(gè)操作過程叫做緩存鎖定(cache locking),緩存鎖定將大大降低 lock 前綴指令的執(zhí)行開銷,但是當(dāng)多處理器之間的競(jìng)爭(zhēng)程度很高或者指令訪問的內(nèi)存地址未對(duì)齊時(shí),仍然會(huì)鎖住總線。
  • 禁止該指令與之前和之后的讀和寫指令重排序。
  • 把寫緩沖區(qū)中的所有數(shù)據(jù)刷新到內(nèi)存中。

上面的第 2 點(diǎn)和第 3 點(diǎn)所具有的內(nèi)存屏障效果,足以同時(shí)實(shí)現(xiàn) volatile 讀和 volatile 寫的內(nèi)存語(yǔ)義。

經(jīng)過上面的這些分析,現(xiàn)在我們終于能明白為什么 JDK 文檔說 CAS 同時(shí)具有 volatile 讀和 volatile 寫的內(nèi)存語(yǔ)義了。

Java 的 CAS 會(huì)使用現(xiàn)代處理器上提供的高效機(jī)器級(jí)別原子指令,這些原子指令以原子方式對(duì)內(nèi)存執(zhí)行讀 - 改 - 寫操作,這是在多處理器中實(shí)現(xiàn)同步的關(guān)鍵(從本質(zhì)上來說,能夠支持原子性讀 - 改 - 寫指令的計(jì)算機(jī)器,是順序計(jì)算圖靈機(jī)的異步等價(jià)機(jī)器,因此任何現(xiàn)代的多處理器都會(huì)去支持某種能對(duì)內(nèi)存執(zhí)行原子性讀 - 改 - 寫操作的原子指令)。同時(shí),volatile 變量的讀 / 寫和 CAS 可以實(shí)現(xiàn)線程之間的通信。把這些特性整合在一起,就形成了整個(gè) concurrent 包得以實(shí)現(xiàn)的基石。如果我們仔細(xì)分析 concurrent 包的源代碼實(shí)現(xiàn),會(huì)發(fā)現(xiàn)一個(gè)通用化的實(shí)現(xiàn)模式:

  • 首先,聲明共享變量為 volatile;
  • 然后,使用 CAS 的原子條件更新來實(shí)現(xiàn)線程之間的同步;
  • 同時(shí),配合以 volatile 的讀 / 寫和 CAS 所具有的 volatile 讀和寫的內(nèi)存語(yǔ)義來實(shí)現(xiàn)線程之間的通信。

AQS,非阻塞數(shù)據(jù)結(jié)構(gòu)和原子變量類(
java.util.concurrent.atomic 包中的類),這些 concurrent 包中的基礎(chǔ)類都是使用這種模式來實(shí)現(xiàn)的,而 concurrent 包中的高層類又是依賴于這些基礎(chǔ)類來實(shí)現(xiàn)的。從整體來看,concurrent 包的實(shí)現(xiàn)示意圖如下:

JVM中的CAS(堆中對(duì)象的分配): 

Java 調(diào)用 new object() 會(huì)創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象會(huì)被分配到 JVM 的堆中。那么這個(gè)對(duì)象到底是怎么在堆中保存的呢?

首先,new object() 執(zhí)行的時(shí)候,這個(gè)對(duì)象需要多大的空間,其實(shí)是已經(jīng)確定的,因?yàn)?java 中的各種數(shù)據(jù)類型,占用多大的空間都是固定的(對(duì)其原理不清楚的請(qǐng)自行Google)。那么接下來的工作就是在堆中找出那么一塊空間用于存放這個(gè)對(duì)象。

在單線程的情況下,一般有兩種分配策略:

  1. 指針碰撞:這種一般適用于內(nèi)存是絕對(duì)規(guī)整的(內(nèi)存是否規(guī)整取決于內(nèi)存回收策略),分配空間的工作只是將指針像空閑內(nèi)存一側(cè)移動(dòng)對(duì)象大小的距離即可。
  2. 空閑列表:這種適用于內(nèi)存非規(guī)整的情況,這種情況下JVM會(huì)維護(hù)一個(gè)內(nèi)存列表,記錄哪些內(nèi)存區(qū)域是空閑的,大小是多少。給對(duì)象分配空間的時(shí)候去空閑列表里查詢到合適的區(qū)域然后進(jìn)行分配即可。

但是JVM不可能一直在單線程狀態(tài)下運(yùn)行,那樣效率太差了。由于再給一個(gè)對(duì)象分配內(nèi)存的時(shí)候不是原子性的操作,至少需要以下幾步:查找空閑列表、分配內(nèi)存、修改空閑列表等等,這是不安全的。解決并發(fā)時(shí)的安全問題也有兩種策略:

  1. CAS:實(shí)際上虛擬機(jī)采用CAS配合上失敗重試的方式保證更新操作的原子性,原理和上面講的一樣。
  2. TLAB:如果使用CAS其實(shí)對(duì)性能還是會(huì)有影響的,所以 JVM 又提出了一種更高級(jí)的優(yōu)化策略:每個(gè)線程在 Java 堆中預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖區(qū)(TLAB),線程內(nèi)部需要分配內(nèi)存時(shí)直接在 TLAB 上分配就行,避免了線程沖突。只有當(dāng)緩沖區(qū)的內(nèi)存用光需要重新分配內(nèi)存的時(shí)候才會(huì)進(jìn)行CAS操作分配更大的內(nèi)存空間。

虛擬機(jī)是否使用TLAB,可以通過-XX:+/-UseTLAB參數(shù)來進(jìn)行配置(jdk5及以后的版本默認(rèn)是啟用TLAB的)。

四、CAS存在的問題:

4.1 ABA 問題

談到 CAS,基本上都要談一下 CAS 的 ABA 問題。CAS 由三個(gè)步驟組成,分別是“讀取-比較-寫回”。考慮這樣一種情況,線程1和線程2同時(shí)執(zhí)行 CAS 邏輯,兩個(gè)線程的執(zhí)行順序如下:

  • 時(shí)刻1:線程1執(zhí)行讀取操作,獲取原值 A,然后線程被切換走
  • 時(shí)刻2:線程2執(zhí)行完成 CAS 操作將原值由 A 修改為 B
  • 時(shí)刻3:線程2再次執(zhí)行 CAS 操作,并將原值由 B 修改為 A
  • 時(shí)刻4:線程1恢復(fù)運(yùn)行,將比較值(compareValue)與原值(oldValue)進(jìn)行比較,發(fā)現(xiàn)兩個(gè)值相等。

然后用新值(newValue)寫入內(nèi)存中,完成 CAS 操作

如上流程,線程1并不知道原值已經(jīng)被修改過了,在它看來并沒什么變化,所以它會(huì)繼續(xù)往下執(zhí)行流程。對(duì)于 ABA 問題,通常的處理措施是對(duì)每一次 CAS 操作設(shè)置版本號(hào)。

ABA問題的解決思路其實(shí)也很簡(jiǎn)單,就是使用版本號(hào)。在變量前面追加上版本號(hào),每次變量更新的時(shí)候把版本號(hào)加1,那么A→B→A就會(huì)變成1A→2B→3A了。

java.util.concurrent.atomic 包下提供了一個(gè)可處理 ABA 問題的原子類 AtomicStampedReference,

從Java1.5開始JDK的atomic包里提供了一個(gè)類AtomicStampedReference來解決ABA問題。這個(gè)類的compareAndSet方法作用是首先檢查當(dāng)前引用是否等于預(yù)期引用,并且當(dāng)前標(biāo)志是否等于預(yù)期標(biāo)志,如果全部相等,則以原子方式將該引用和該標(biāo)志的值設(shè)置為給定的更新值。

4.2 循環(huán)時(shí)間長(zhǎng)開銷大

自旋CAS(不成功,就一直循環(huán)執(zhí)行,直到成功) 如果長(zhǎng)時(shí)間不成功,會(huì)給 CPU 帶來非常大的執(zhí)行開銷。如果JVM能支持處理器提供的 pause 指令那么效率會(huì)有一定的提升,pause指令有兩個(gè)作用,第一它可以延遲流水線執(zhí)行指令(de-pipeline),使 CPU 不會(huì)消耗過多的執(zhí)行資源,延遲的時(shí)間取決于具體實(shí)現(xiàn)的版本,在一些處理器上延遲時(shí)間是零。第二它可以避免在退出循環(huán)的時(shí)候因內(nèi)存順序沖突(memory order violation)而引起 CPU 流水線被清空(CPU pipeline flush),從而提高 CPU 的執(zhí)行效率。

4.3 只能保證一個(gè)共享變量的原子操作

當(dāng)對(duì)一個(gè)共享變量執(zhí)行操作時(shí),我們可以使用循環(huán) CAS 的方式來保證原子操作,但是對(duì)多個(gè)共享變量操作時(shí),循環(huán) CAS 就無(wú)法保證操作的原子性,這個(gè)時(shí)候就可以用鎖,或者有一個(gè)取巧的辦法,就是把多個(gè)共享變量合并成一個(gè)共享變量來操作。比如有兩個(gè)共享變量 i=2,j=a,合并一下 ij=2a,然后用CAS來操作ij。從Java1.5開始JDK提供了 AtomicReference 類來保證引用對(duì)象之間的原子性,你可以把多個(gè)變量放在一個(gè)對(duì)象里來進(jìn)行 CAS 操作。

CAS 與 Synchronized 的使用情景:   

  1. 對(duì)于資源競(jìng)爭(zhēng)較少(線程沖突較輕)的情況,使用synchronized同步鎖進(jìn)行線程阻塞和喚醒切換以及用戶態(tài)內(nèi)核態(tài)間的切換操作額外浪費(fèi)消耗cpu資源;而CAS基于硬件實(shí)現(xiàn),不需要進(jìn)入內(nèi)核,不需要切換線程,操作自旋幾率較少,因此可以獲得更高的性能。
  2. 對(duì)于資源競(jìng)爭(zhēng)嚴(yán)重(線程沖突嚴(yán)重)的情況,CAS自旋的概率會(huì)比較大,從而浪費(fèi)更多的CPU資源,效率低于synchronized。

補(bǔ)充: synchronized 在 jdk1.6 之后,已經(jīng)改進(jìn)優(yōu)化。synchronized 的底層實(shí)現(xiàn)主要依靠 Lock-Free 的隊(duì)列,基本思路是自旋后阻塞,競(jìng)爭(zhēng)切換后繼續(xù)競(jìng)爭(zhēng)鎖,稍微犧牲了公平性,但獲得了高吞吐量。在線程沖突較少的情況下,可以獲得和 CAS 類似的性能;而線程沖突嚴(yán)重的情況下,性能遠(yuǎn)高于 CAS。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2021-01-15 05:12:14

Java并發(fā)樂觀鎖

2024-08-12 17:36:54

2021-11-08 09:18:01

CAS面試場(chǎng)景

2025-09-08 00:00:00

并發(fā)模塊并發(fā)性能異步編程

2020-09-16 07:56:28

多線程讀寫鎖悲觀鎖

2021-04-26 17:23:21

JavaCAS原理

2025-09-23 02:15:00

2023-07-05 08:18:54

Atomic類樂觀鎖悲觀鎖

2020-07-06 08:03:32

Java悲觀鎖樂觀鎖

2020-11-30 11:01:34

反射用途實(shí)現(xiàn)

2025-10-31 02:00:00

2020-10-15 06:26:24

高并發(fā)場(chǎng)景冰河

2025-09-18 08:53:20

2025-09-22 08:26:37

2009-09-24 14:43:53

Hibernate樂觀

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級(jí)別幻讀

2025-04-16 00:00:01

JWT客戶端存儲(chǔ)加密令

2024-02-27 15:23:48

RedLock算法Redis

2020-10-26 07:07:50

線程安全框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

天天综合色天天综合色h| 激情五月婷婷综合网| 亚洲精品国产综合久久| 天天天干夜夜夜操| 综合久久2019| 99久久久精品免费观看国产蜜| 日韩av电影院| 国产大片免费看| 欧美禁忌电影网| 日韩精品一区在线| 999精品视频在线| 中文国产字幕在线观看| 久久久www免费人成精品| 亚洲一区二区三区sesese| 国产精品久久久久久久妇| 国产精品x453.com| 精品视频偷偷看在线观看| 成人性生交视频免费观看| 吉吉日韩欧美| 亚洲电影在线免费观看| 一区二区三区国产福利| 日韩a在线看| 成人毛片在线观看| 91久久中文字幕| 五月激情丁香网| 一区二区三区精品视频在线观看| 久久亚洲综合国产精品99麻豆精品福利 | 欧美午夜不卡| 中文字幕日韩欧美在线| 91porn在线| 亚瑟国产精品| 欧美视频三区在线播放| 欧美三级一级片| 国产在线xxx| 亚洲色图视频网| 亚洲 日韩 国产第一区| 国产三级视频在线| 久久久久久麻豆| 久久亚洲午夜电影| 日韩在线视频第一页| 国产福利视频一区二区三区| 国产在线观看一区二区三区| 在线观看一二三区| 日韩av中文字幕一区二区| 欧美一区二区三区精品电影| 日韩免费一二三区| 欧美日韩亚洲三区| 久久99精品视频一区97| 男女羞羞免费视频| 欧美成人有码| 欧美老女人性视频| 欧美日韩在线观看免费| 综合日韩在线| 久操成人在线视频| 精品午夜福利视频| 国产一区二区中文| 91av免费观看91av精品在线| 97超碰人人干| 性高湖久久久久久久久| 日韩av电影国产| 一级一级黄色片| 麻豆国产精品一区二区三区 | 日韩成人视屏| 欧美成人一区二区三区片免费| 欧美国产日韩在线视频| av成人综合| 亚洲大胆人体视频| 美女脱光内衣内裤| 日韩在线高清| 欧美久久精品午夜青青大伊人| 印度午夜性春猛xxx交| 伊人久久大香线蕉av超碰演员| 97色在线观看| 姑娘第5集在线观看免费好剧| 蜜桃传媒麻豆第一区在线观看| 国产主播喷水一区二区| 性做久久久久久久久久| 91在线视频播放地址| 日本免费高清一区二区| 麻豆视频在线播放| 亚洲二区在线视频| 天天影视综合色| 精品国产乱码久久久久久樱花| 欧美精品一区二区久久久| 亚洲第一黄色网址| 999久久久91| 91黄色8090| 中文字幕无线码一区| 国产毛片精品国产一区二区三区| 国产麻豆日韩| av大全在线免费看| 亚洲风情在线资源站| 黄色免费网址大全| 国产精品久久久久av蜜臀| 亚洲欧美一区二区三区情侣bbw| 五月综合色婷婷| 亚洲综合欧美| 成人av资源网| 国产粉嫩一区二区三区在线观看 | 草b视频在线观看| 成人av三级| 欧美一区二区三区电影| 受虐m奴xxx在线观看| 欧美三级第一页| 国产精品视频一| 午夜视频www| 亚洲摸摸操操av| 99久久激情视频| 91久久偷偷做嫩草影院电| 欲色天天网综合久久| 国产稀缺真实呦乱在线| 国产在线一区二区综合免费视频| 精品国产日本| 一二三四区在线观看| 欧美性生活久久| 三级黄色片网站| 欧美精选在线| 成人h猎奇视频网站| 黄色毛片在线观看| 亚洲.国产.中文慕字在线| 伊人国产精品视频| 97精品一区| 国产精品精品视频一区二区三区| 少妇高潮一区二区三区99小说| 亚洲欧美自拍偷拍| 美女少妇一区二区| 亚洲bt欧美bt精品777| 国模精品视频一区二区| 国产99久久九九精品无码免费| 欧美韩国日本一区| 成人在线激情网| 自拍欧美一区| 欧美一级免费视频| 亚洲欧美自偷自拍| 精品久久香蕉国产线看观看gif| 人妻互换一二三区激情视频| 在线看片不卡| 91亚洲午夜在线| 国产一二区在线| 欧美人伦禁忌dvd放荡欲情| 黄色三级生活片| 日本麻豆一区二区三区视频| 欧洲一区二区在线| 欧美电影免费观看网站| 亚洲欧美一区二区激情| 免费又黄又爽又猛大片午夜| 久久综合久色欧美综合狠狠| 国产中文字幕免费观看| 日韩欧美中文字幕电影| 欧美中文字幕视频| 国产日韩精品在线看| 在线视频国产一区| 日本污视频网站| 日韩av电影天堂| 影音先锋欧美在线| 成人黄色91| 欧美激情一区二区三区在线视频观看 | 国产精品一区二区在线观看| av免费不卡| 亚洲美女av网站| 国产无遮挡又黄又爽又色视频| 国产欧美一区在线| 亚洲精品在线视频播放| 欧美欧美天天天天操| 国产精品视频在线免费观看| 亚洲美女久久精品| 中文字幕在线视频日韩| 国产黄频在线观看| 欧美日韩激情视频8区| 在线不卡av电影| 激情伊人五月天久久综合| 国产精品免费看久久久无码| 另类尿喷潮videofree| 青草青草久热精品视频在线网站 | 成人亚洲免费视频| 欧美午夜国产| 欧美成熟毛茸茸复古| 国产乱子精品一区二区在线观看| 欧美乱大交xxxxx另类电影| 丰满肉嫩西川结衣av| 色婷婷综合激情| 国产天堂av在线| 99re成人在线| caoporm在线视频| 日韩亚洲国产欧美| 午夜精品一区二区在线观看 | 亚洲欧美在线x视频| 国产又粗又长又黄| 天天爽夜夜爽夜夜爽精品视频| 久久免费手机视频| 粉嫩av一区二区三区| 超碰在线人人爱| 国产精品v日韩精品v欧美精品网站| 国产视频不卡| 亚洲一区二区三区久久久| 78m国产成人精品视频| 蜜桃视频网站在线| 亚洲男人天堂古典| 亚洲春色一区二区三区| 欧美三区在线视频| 日本少妇bbwbbw精品| 中文字幕一区二区不卡| 欧美精品黑人猛交高潮| 国产白丝网站精品污在线入口 | 国产一区二区美女| 成人在线观看a| 黑丝一区二区三区| 在线成人性视频| 国产精品欧美在线观看| 国产99在线免费| 中文字幕日本一区| 国产精品久久久久久久久久东京| av剧情在线观看| 欧美日韩福利视频| 免费a在线看| 伊人伊人伊人久久| 无码精品一区二区三区在线| 日韩欧美国产一区二区在线播放 | 亚洲国内高清视频| 国产黄色av片| 91精品午夜视频| 中文字幕乱码中文字幕| 色猫猫国产区一区二在线视频| 久久9999久久免费精品国产| 亚洲精品免费一二三区| 日本黄色片免费观看| 欧美国产1区2区| 怡红院一区二区三区| 久久久久久97三级| 久久久久国产精品区片区无码| 国产精品小仙女| 中文字幕一区二区三区四| 蜜桃久久av一区| 色噜噜狠狠永久免费| 青娱乐精品视频| 密臀av一区二区三区| 久久久亚洲人| 成人在线免费播放视频| 三级不卡在线观看| 久久久久狠狠高潮亚洲精品| 国产毛片久久| 日本wwww视频| 老牛影视一区二区三区| 波多野结衣家庭教师视频| 国产日韩一区二区三区在线| 好吊妞无缓冲视频观看| 亚洲美女一区| 欧美牲交a欧美牲交aⅴ免费真 | 在线能看的av网站| 激情五月激情综合网| 久久久久久国产精品日本| 国产真实乱偷精品视频免| 99999精品| 丁香激情综合国产| 波多野结衣加勒比| 久久婷婷国产综合国色天香| 在线国产视频一区| 国产精品视频看| 好吊日在线视频| 亚洲自拍偷拍九九九| 日韩欧美性视频| 91国内精品野花午夜精品| 老熟妇一区二区三区啪啪| 欧美日韩成人高清| 成人av免费播放| 国产视频精品免费播放| 国产成人天天5g影院在线观看| 日韩在线观看你懂的| 在线电影福利片| 久久久这里只有精品视频| 一区二区三区四区日本视频| 国产精品日韩在线一区| 999精品视频在线观看| 不卡一区二区三区视频| 一区二区三区韩国免费中文网站| 婷婷四月色综合| 中文字幕人成人乱码| 日本午夜激情视频| 日产国产欧美视频一区精品| 中文字幕一区久久| 99久久久久久99| 久久视频一区二区三区| 亚洲一区二区综合| 午夜一级黄色片| 精品国产sm最大网站免费看| 国产三级视频在线| 欧美激情乱人伦| 欧美性理论片在线观看片免费| 91亚洲精品久久久| 亚洲人成精品久久久 | jk漫画禁漫成人入口| 成人欧美一区二区三区黑人孕妇| 欧美人与动xxxxz0oz| 一区二区三区电影| 久久激情综合| 性色av蜜臀av浪潮av老女人| 国产精品毛片高清在线完整版| 国产无套粉嫩白浆内谢| 欧美久久免费观看| 你懂得网站在线| 欧美激情亚洲精品| 欧美视频第一| 日本视频一区在线观看| 国产一区日韩欧美| 夜夜夜夜夜夜操| 久久久精品综合| 四虎永久在线精品| 91精品婷婷国产综合久久竹菊| 日本在线一二三| 欧美激情亚洲视频| 四虎国产精品免费久久5151| 欧美久久综合性欧美| 黄色成人在线网址| 污视频在线观看免费网站| 国产日产亚洲精品系列| 成年免费在线观看| 欧美成人欧美edvon| 毛片av在线| 国产精品中文字幕在线观看| 九九热线有精品视频99| 久久国产精品网| 国产馆精品极品| 丁香花五月激情| 欧美另类一区二区三区| av中文天堂在线| 国产精品wwww| 亚洲影院天堂中文av色| 无码人妻丰满熟妇区96| 粉嫩一区二区三区性色av| 91aaa在线观看| 5月丁香婷婷综合| 无遮挡动作视频在线观看免费入口| 国产成人短视频| 国产麻豆一区二区三区精品视频| 国产综合中文字幕| 99亚偷拍自图区亚洲| 日韩av男人天堂| 亚洲国产中文字幕久久网| brazzers在线观看| 国产伦精品一区二区三区视频孕妇| 欧美日韩亚洲一区三区| 少妇欧美激情一区二区三区| 亚洲免费av观看| 亚洲天堂自拍偷拍| 色av吧综合网| 国模视频一区| 先锋影音一区二区三区| 另类综合日韩欧美亚洲| 中文字幕观看av| 欧美一区2区视频在线观看| 成人video亚洲精品| 91成人免费观看| 亚洲婷婷免费| 亚洲专区区免费| 欧美性受xxxx黑人xyx| 麻豆传媒在线观看| aa日韩免费精品视频一| 亚洲大胆在线| 麻豆精品免费视频| 欧美偷拍一区二区| 黄色网页在线播放| 国产成人精品日本亚洲11 | 一本色道久久亚洲综合精品蜜桃 | av大片免费观看| 亚洲视屏在线播放| va天堂va亚洲va影视| 国内少妇毛片视频| 久久欧美一区二区| 亚洲熟妇av乱码在线观看| 久久99久久99精品免观看粉嫩 | www.久久草.com| 国产免费裸体视频| 久久伊人中文字幕| 国产麻豆一精品一男同| 4p变态网欧美系列| 999国产精品| 亚洲蜜桃精久久久久久久久久久久| 91福利精品第一导航| jizz性欧美10| 欧美成人综合一区| 国产一区二区在线电影| 日本三级一区二区| www.日韩不卡电影av| 秋霞影视一区二区三区| 中国黄色片免费看| 香蕉成人伊视频在线观看| 国产最新视频在线观看| 97人人模人人爽视频一区二区| 亚洲永久视频| 国产精品久久久久久久精| 亚洲免费电影在线观看| 欧美专区一区| 国内自拍视频网| 亚洲va国产天堂va久久en| 自拍视频在线网| 久久亚洲高清| 大陆成人av片| 91一区二区视频| 日韩av色在线| 亚洲人www|