精品欧美一区二区三区在线观看 _久久久久国色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)

国产成人福利网站| 精品国产欧美一区二区| 亚洲国产精品视频一区| 国产一区二区在线视频聊天| 欧美 亚欧 日韩视频在线 | 在线免费观看国产精品| 日本a口亚洲| 亚洲精品在线电影| 在线免费视频a| 精灵使的剑舞无删减版在线观看| 26uuu亚洲综合色| 91视频国产一区| 五月婷婷视频在线| 五月精品视频| 亚洲欧美第一页| **亚洲第一综合导航网站| 国产精品不卡av| 欧美freesextv| 亚洲精品按摩视频| 午夜一级免费视频| 国产在线91| 国产一区二区在线看| 欧美一乱一性一交一视频| 91精产国品一二三产区别沈先生| 福利小视频在线| 中文字幕亚洲综合久久菠萝蜜| 精选一区二区三区四区五区| 国产伦理一区二区| 日日摸夜夜添夜夜添亚洲女人| 欧美激情免费视频| 三级全黄做爰视频| 精品久久中文| 日韩欧美一区二区在线| 裸体裸乳免费看| 91短视频版在线观看www免费| 久久综合狠狠| 68精品久久久久久欧美| 三级在线观看免费大全| 国产一区二区在线| 日韩av在线不卡| 少妇熟女视频一区二区三区| 四虎国产精品永久在线国在线| 色婷婷综合在线| 自慰无码一区二区三区| 毛片网站在线看| 亚洲日本一区二区| 精品久久免费观看| 在线观看免费版| 国产精品系列在线| 成人h猎奇视频网站| 亚洲视频小说| av影片在线看| 久久亚洲一区二区三区四区| 久久久国产精品一区| 亚洲av人人澡人人爽人人夜夜| 男女视频在线| 亚洲靠逼com| 福利在线小视频| 69xxx在线| 一区二区三区在线视频免费观看| 久久久久久久久久久久久国产| а√资源新版在线天堂| 亚洲美女免费在线| 成人国产在线看| heyzo高清国产精品| 亚洲国产日韩精品| 免费毛片网站在线观看| 美州a亚洲一视本频v色道| 99久久久国产精品| 欧美极品视频一区二区三区| 邻家有女韩剧在线观看国语| 久久久国产精品午夜一区ai换脸| 日韩国产高清一区| 精品国产一级片| 懂色av噜噜一区二区三区av| 国产精品一区二区三区免费观看 | 亚洲最大黄网| 久久99久久99精品免观看粉嫩 | 亚洲国产精品第一页| 91精品短视频| 日韩av在线网| 国产第一页精品| 女人色偷偷aa久久天堂| 久久久久久中文字幕| 日本天堂网在线| 毛片av一区二区| 99九九电视剧免费观看| 亚洲 欧美 精品| 中文一区二区在线观看| 国产乱子伦精品视频| 阿v视频在线| 日本一区二区三区高清不卡| 一本一道久久久a久久久精品91 | 激情综合网婷婷| 国产69精品久久久久按摩| 欧美一区二区三区色| 小毛片在线观看| av亚洲免费| 欧美国产日韩一区二区在线观看| 人人干人人干人人干| 奇米在线7777在线精品 | 成人三级视频在线播放| 国产精品.xx视频.xxtv| 欧美成人伊人久久综合网| 国产免费又粗又猛又爽| 少妇av在线播放| 国产婷婷色一区二区三区四区 | 午夜精品福利影院| 神马久久久久久| 国产无遮挡免费视频| 日韩av中文在线观看| 3d精品h动漫啪啪一区二区| 手机福利小视频在线播放| 中文字幕亚洲精品在线观看| 国产黄视频在线| 欧美第一在线视频| 中文字幕亚洲色图| 国产又黄又爽又色| 国产在线播放一区三区四| 欧美一级片免费观看| 手机在线免费av| 欧美在线视频全部完| 在线观看国产三级| 欧美高清日韩| 国产区亚洲区欧美区| 欧美女优在线观看| 亚洲国产视频一区二区| 在线黄色免费观看| 久久93精品国产91久久综合| 欧美激情久久久久久| av中文字幕播放| 国产精品成人免费| 国产精品人人妻人人爽人人牛| y111111国产精品久久久| 日韩一区二区三区观看| 青娱乐国产视频| 国产女优一区| 精品国产中文字幕| 18video性欧美19sex高清| 91麻豆精品91久久久久同性| avhd101老司机| 日韩中文字幕不卡| 欧美重口乱码一区二区| 国产欧洲在线| 亚洲国产天堂久久综合网| 久久久久久久九九九九| 国产在线精品视频| 六月婷婷激情网| 国产精品高清一区二区 | 天堂亚洲精品| 日韩精品一区二区三区四区| 中文字幕av免费在线观看| 精品在线免费视频| 国产91精品入口17c| av毛片在线免费看| 欧美不卡在线视频| 国产在线观看免费视频今夜| 国产91精品久久久久久久网曝门| 97在线免费视频观看| 澳门成人av| 性欧美xxxx交| 精品999视频| 欧美性欧美巨大黑白大战| 综合 欧美 亚洲日本| 麻豆精品一区二区av白丝在线| 亚洲国产精品日韩| 国产亚洲字幕| 性色av一区二区三区免费| 五月天婷婷视频| 91高清在线观看| 欧美自拍偷拍网| 国产精品亚洲一区二区三区在线| 国产在线视频综合| 亚洲人挤奶视频| 国产精品日韩欧美大师| 成人video亚洲精品| 精品国产91九色蝌蚪| 久久久久久少妇| 国产精品久久久久影视| 最新中文字幕日本| 噜噜爱69成人精品| 宅男在线精品国产免费观看| a看欧美黄色女同性恋| 欧美性做爰毛片| 欧美被日视频| 欧美性猛交xxxx乱大交极品| 国产精品国产三级国产专业不| 激情另类小说区图片区视频区| 日本男女交配视频| 黄色不卡一区| 99国产盗摄| 超碰这里只有精品| 欧美男插女视频| 黄色软件在线| 欧美videossexotv100| 波多野结衣绝顶大高潮| 亚洲免费看黄网站| 国产男男chinese网站| 国产尤物一区二区| 日韩av一二三四| 欧美成人亚洲| 亚洲一区三区电影在线观看| 欧美大胆a级| 91超碰在线免费观看| 欧美xo影院| 久久免费高清视频| 免费观看成人高潮| 亚洲欧美日韩中文视频| www日本在线| 欧美三区在线观看| 日本中文字幕在线免费观看| 国产精品免费aⅴ片在线观看| 美女久久久久久久久| 精品亚洲成a人| 精品久久久久久久无码| 亚洲精品色图| 久久av免费一区| 国产高清日韩| 国产欧美日韩专区发布| 成人免费短视频| 国产+成+人+亚洲欧洲| 国产素人视频在线观看| 亚洲色图日韩av| 亚洲av成人精品一区二区三区在线播放| 欧美日韩的一区二区| 久久久久久在线观看| 亚洲高清免费在线| 黄色一级免费视频| 国产.精品.日韩.另类.中文.在线.播放 | 全色精品综合影院| 亚洲成人激情在线| 91香蕉在线视频| 依依成人综合视频| 在线看的片片片免费| 国产精品久久影院| 免费在线观看a视频| 久久久三级国产网站| 最新在线黄色网址| 97se亚洲国产综合自在线| 日本a级片免费观看| 精品99视频| 麻豆成人小视频| 澳门成人av| 国产精品二区三区| 亚洲**毛片| 5g国产欧美日韩视频| 精品久久国产一区| 91久久久久久久久久久久久| 999色成人| 成人有码视频在线播放| 亚洲电影二区| 成人网在线免费观看| 国产情侣一区在线| 91丨九色丨国产在线| 日本一区二区三区视频在线看| 成人精品在线观看| 欧美激情三级| 国产视频一区二区不卡| 欧美日韩破处| 亚洲毛茸茸少妇高潮呻吟| 日韩美女在线观看| 做爰高潮hd色即是空| 久久精品国产福利| 国产精品丝袜久久久久久高清| 朝桐光一区二区| 国产精品网站大全| 国产精久久一区二区| av免费观看久久| 日韩高清三区| 婷婷四月色综合| 亚洲欧洲美洲一区二区三区| 可以在线看黄的网站| 亚洲激情社区| 国产xxxxx视频| 黄页视频在线91| 亚洲美女高潮久久久| 91色综合久久久久婷婷| 少妇人妻好深好紧精品无码| 国产精品免费av| 精品在线视频观看| 色成人在线视频| 97国产成人无码精品久久久| 日韩免费一区二区| 高清毛片aaaaaaaaa片| 亚洲精品一区久久久久久| 一级日本在线| 欧美欧美欧美欧美| 国产成人毛毛毛片| 日韩精品中文字幕在线播放| 草碰在线视频| 欧美国产日韩精品| 色老太综合网| 亚洲一区二区久久久久久| 澳门成人av| 婷婷五月色综合| 亚洲一级特黄| 免费一级特黄录像| 成人午夜大片免费观看| 亚洲性猛交xxxx乱大交| 亚洲精品日产精品乱码不卡| 男人天堂2024| 欧美日韩亚洲成人| 国产精品99精品无码视| 波多野结衣一区二区三区| 亚洲午夜av电影| 在线观看岛国av| 美女视频黄 久久| 99精品一区二区三区无码吞精| 亚洲国产精品成人综合色在线婷婷| 久久av高潮av无码av喷吹| 色综合久久久久久久久久久| 国产绳艺sm调教室论坛| 国产一区二区三区欧美| av丝袜在线| 亚洲a区在线视频| 精品国产一区探花在线观看| 国产精品裸体瑜伽视频| 国产美女精品人人做人人爽| 久操视频在线观看免费| 精品日本美女福利在线观看| 国产成人精品白浆久久69| 国产一区二区三区视频在线观看| 爱啪视频在线观看视频免费| 91精品在线观| 久久麻豆精品| 99视频精品免费| 91在线porny国产在线看| 久久久香蕉视频| 欧美精品在线一区二区三区| 中文日本在线观看| 国产成人精品在线| 亚洲免费成人av在线| 日韩亚洲欧美视频| 国产99久久久久| 欧美日韩在线视频免费播放| 欧美欧美欧美欧美| 欧美性猛交xxx乱大交3蜜桃| 国产成人jvid在线播放| 你懂的视频欧美| 777久久久精品一区二区三区| 成人精品视频一区二区三区尤物| 国产精品久久久精品四季影院| 欧美高清性hdvideosex| 午夜免费播放观看在线视频| 国产精品三级网站| 精品精品99| 黄色手机在线视频| 中文字幕欧美激情一区| 中文字幕永久在线视频| 精品欧美激情精品一区| 免费av一级片| 欧美激情国产高清| 成人午夜大片| 国产免费黄色一级片| 亚洲h色精品| 这里只有精品在线观看| 能看毛片的网站| 国产大片一区二区| avove在线播放| 精品福利一区二区三区 | 国色天香久久精品国产一区| 美国av在线播放| 国产精品影音先锋| 九九视频免费观看| 亚洲成人激情在线| jizz内谢中国亚洲jizz| 日本高清不卡一区二区三| 日本中文在线一区| 午夜国产福利视频| 日韩一二在线观看| а√天堂8资源在线| 欧美日本亚洲| 久久99国产精品尤物| 激情五月少妇a| 亚洲国产高潮在线观看| 亚洲一级少妇| 一本久道久久综合狠狠爱亚洲精品| 国产综合色在线视频区| 久久免费视频精品| 亚洲欧美综合图区| www.久久草.com| 国产91xxx| 国产精品女主播在线观看| 国产夫妻性生活视频| 羞羞色国产精品| 日韩一级毛片| 色哟哟无码精品一区二区三区| 色综合激情五月| 性欧美video高清bbw| 欧美少妇一区| 国产精品系列在线播放| 岛国av中文字幕| 久久中文字幕一区| 夜夜躁狠狠躁日日躁2021日韩| 亚洲国产日韩欧美在线观看| 亚洲第一搞黄网站| 永久免费av在线| 久久精品国产精品青草色艺| 精品一区中文字幕| 日韩视频在线观看一区|