91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java性能 -- CAS樂觀鎖

發布時間:2020-05-17 18:15:23 來源:網絡 閱讀:103 作者:Java成神路 欄目:編程語言

synchronized / Lock / CAS

  1. synchronized和Lock實現的同步鎖機制,都屬于悲觀鎖,而CAS屬于樂觀鎖
  2. 悲觀鎖在高并發的場景下,激烈的鎖競爭會造成線程阻塞,而大量阻塞線程會導致系統的上下文切換,增加系統的性能開銷

樂觀鎖

  1. 樂觀鎖:在操作共享資源時,總是抱著樂觀的態度進行,認為自己能夠完成操作
  2. 但實際上,當多個線程同時操作一個共享資源時,只有一個線程會成功,失敗的線程不會被掛起,僅僅只是返回
  3. 樂觀鎖相比于悲觀鎖來說,不會帶來死鎖、饑餓等活性故障問題,線程間的相互影響也遠遠比悲觀鎖要小
    • 樂觀鎖沒有因競爭而造成的系統上下文切換,所以在性能上更勝一籌

實現原理

  1. CAS是實現樂觀鎖的核心算法,包含3個參數:V(需要更新的變量),E(預期值)、N(最新值)
  2. 只有V等于E時,V才會被設置為N
  3. 如果V不等于E了,說明其它線程已經更新了V,此時該線程不做操作,返回V的真實值

CAS實現原子操作

AtomicInteger是基于CAS實現的一個線程安全的整型類,Unsafe調用CPU底層指令實現原子操作

// java.util.concurrent.atomic.AtomicInteger
public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

public final int getAndDecrement() {
    return unsafe.getAndAddInt(this, valueOffset, -1);
}
// sun.misc.Unsafe
public final int getAndAddInt(Object o, long offset, int delta) {
    int v;
    do {
        v = getIntVolatile(o, offset);
    } while (!compareAndSwapInt(o, offset, v, v + delta));
    return v;
}

public native int     getIntVolatile(Object o, long offset);

public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);

處理器實現原子操作

  1. CAS是調用處理器底層指令來實現原子操作的
  2. 處理器和物理內存之間的通信速度要遠低于處理器間的處理速度,所以處理器有自己的內部緩存(L1/L2/L3)
  3. 服務器通常為多處理器,并且處理器是多核的,每個處理器維護了一塊字節的緩存存,每個內核也維護了一塊字節的緩存
    • 此時在多線程并發就會存在緩存不一致的問題,從而導致數據不一致
  4. 處理器提供了總線鎖定緩存鎖定兩種機制來保證復雜內存操作的原子性
    • 總線鎖定
      • 當處理器要操作一個共享變量時,會在總線上會發出一個Lock信號,此時其它處理器就不能操作共享變量了
      • 總線鎖定在阻塞其他處理器獲取該共享變量的操作請求時,也可能會導致大量阻塞,從而增加系統的性能開銷
    • 緩存鎖定(后來出現)
      • 當某個處理器對緩存中的共享變量進行了操作,就會通知其他處理器放棄存儲或者重新讀取該共享變量
      • 目前最新的處理器都支持緩存鎖定機制

Java性能 -- CAS樂觀鎖

優化CAS樂觀鎖

  1. 樂觀鎖在并發性能上要優于悲觀鎖
    • 但在寫大于讀的操作場景下,CAS失敗的可能性增大,如果循環CAS,會長時間占用CPU
    • 例如上面的AtomicInteger#getAndIncrement
  2. JDK 1.8中,提供了新的原子類LongAdder
    • LongAdder在高并發場景下會比AtomicInteger和AtomicLong的性能更好,代價是消耗更多的內存空間
      • 核心思想:空間換時間
      • 實現原理:降低操作共享變量的并發數
    • LongAdder內部由一個base變量和一個cell[]數組組成
      • 當只有一個寫線程(沒有競爭
        • LongAdder會直接使用base變量作為原子操作變量,通過CAS操作修改base變量
      • 當有多個寫線程(存在競爭
        • 除了占用base變量的一個寫線程外,其他寫線程的value值會分散到cell數組中
        • 不同線程會命中到數組的不同槽中,各個線程只對自己槽中的value進行CAS操作
        • value=base+∑ni=0Cell[i]
    • LongAdder在操作后的返回值只是一個近似準確的值,但最終返回的是一個準確的值
      • LongAdder不適合實時性要求較高的場景

性能對比

Java性能 -- CAS樂觀鎖

  1. 讀大于寫,讀寫鎖ReentrantReadWriteLock、讀寫鎖StampedLock、樂觀鎖LongAdder的性能最好
  2. 寫大于讀,樂觀鎖的性能最好,其他四種鎖的性能差不多
  3. 讀約等于寫,兩種讀寫鎖和樂觀鎖的性能要優于synchronized和Lock

小結

  1. 樂觀鎖的常見使用場景:數據庫更新
    • 為每條數據定義一個版本號,在更新前獲取版本號,在更新數據時,再判斷版本號是否被更新過,如果沒有才更新數據
  2. CAS樂觀鎖的使用比較受限,因為樂觀鎖只能保證單個變量操作的原子性
  3. CAS樂觀鎖在高并發寫大于讀的場景下
    • 大部分線程的原子操作會失敗,失敗后的線程將不斷重試CAS原子操作,導致大量線程長時間占用CPU資源
    • JDK 1.8中,新增了原子類LongAdder,采用空間換時間的思路解決了這個問題,但實時性不高
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

深州市| 二手房| 东至县| 通化县| 故城县| 渝中区| 扶绥县| 玛沁县| 富阳市| 孝感市| 宁陕县| 扎兰屯市| 云霄县| 志丹县| 根河市| 杭州市| 新余市| 淮南市| 盐城市| 丰城市| 乌拉特后旗| 泸西县| 壤塘县| 夏津县| 周宁县| 泾川县| 北海市| 呼和浩特市| 德惠市| 治县。| 荃湾区| 伊川县| 西城区| 九江县| 水城县| 铁岭县| 丰都县| 鸡泽县| 青浦区| 梓潼县| 勐海县|