日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CAS操作与ABA问题

發布時間:2024/3/24 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CAS操作与ABA问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們在使用鎖時,線程獲取鎖是一種悲觀鎖策略,即假設每一次執行臨界區代碼都會產生沖突, 所以當前線程獲取到鎖的時候同時也會阻塞其他線程獲取該鎖。而CAS操作(又稱為無鎖操作)是一種樂觀鎖策略,它假設所有線程訪問共享資源的時候不會出現沖突,既然不會出現沖突自然而然就不會阻塞其他線程的操作。因此,線程就不會出現阻塞停頓的狀態。那么,如果出現沖突了怎么辦?無鎖操作是使用CAS(compare and swap)又叫做比較交換來鑒別線程是否出現沖突,出現沖突就重試當前操作直到沒有沖突為止。

CAS的操作過程

CAS即Compare and Swap,CAS比較交換的過程可以通俗的理解為CAS(V、A、B),包含三個值分別為: V內存中實際值、 A預期原值(舊值) 、B更新的新值。當V和A相同時,也就是說舊值和內存中實際的值相同表明該值沒有被其他線程更改過,即該舊值A就是目前來說最新的值了,自然而然可以將新值B賦值給V。反之,V和A不相同,表明該值已經被其他線程改過了則該舊值A不是最新版本的值了,所以不能將新值B賦給V,返回V即可。當多個線程使用CAS操作一個變量時,只有一個線程會成功,并成功更新,其余會失敗。失敗的線程會重新嘗試,當然也可以選擇掛起線程。

CAS的實現需要硬件指令集的支撐,在JDK1.5后虛擬機才可以使用處理器提供的CMPXCHG指令實現。CAS支持原子更新操作,適用于計數器,序列發生器等場景(序列發生器就是用來給變量自增的工具),CAS屬于樂觀鎖機制,號稱lock-free(其實只是上層感知無鎖,底層還是有加鎖操作的)。CAS操作失敗時由開發者決定是繼續嘗試還是執行別的操作。

基于CAS實現的工具

java.util.concurrent包都中的實現類都是基于volatile和CAS來實現的。尤其java.util.concurrent.atomic包下的原子類。 就拿AtomicInteger來說:

可以看到 AtomicInteger 底層用的是volatile的變量和CAS來進行更改數據的。volatile保證可見性,多線程并發時,一個線程修改數據,可以保證其它線程立馬看到修改后的值,CAS則保證數據更新的原子性。

CAS多數情況下對開發者來說是透明的。J.U.C的atomic包提供了常用的原子性數據類型以及引用、數組等相關原子類型和更新操作工具,是很多線程安全程序的首選。Unsafe類雖提供CAS服務,但因能夠操縱任意內存地址讀寫而有隱患。JDK9以后,可以使用Variable Handle API來替代Unsafe

模擬實現CAS

CAS需要硬件層面的支持,所以模擬還是用synchronized來實現一下:

public class TestImplementCAS {
public static void main(String[] args) {
final CompareAndSwap cas = new CompareAndSwap();

for (int i = 0; i < 10; i++) {
new Thread(()->{
int expectedValue = cas.get();
boolean b = cas.compareAndSet(expectedValue, (int)(Math.random() * 101));
System.out.println(b);
}).start();
}
}
}

class CompareAndSwap{
private int value;

//獲取內存值
public synchronized int get(){
return value;
}

//比較
public synchronized int compareAndSwap(int expectedValue, int newValue){
int oldValue = value;

if(oldValue == expectedValue){
this.value = newValue;
}

return oldValue;
}

//設置
public synchronized boolean compareAndSet(int expectedValue, int newValue){
return expectedValue == compareAndSwap(expectedValue, newValue);
}
}

CAS的缺點

1、ABA問題

因為CAS會檢查舊值有沒有變化,這里存在這樣一個有意思的問題。比如一個舊值A變為了成B,然后再變成A,剛好在做CAS時檢查發現舊值并沒有變化依然為A,但是實際上的確發生了變化。解決方案可以沿襲數據庫中常用的樂觀鎖方式,添加一個版本號可以解決。在JDK1.5后的atomic包中提供 了AtomicStampedReference來解決ABA問題,解決思路就是這樣的。如果需要解決ABA問題,互斥與同步可能比CAS更高效。

2、自旋會浪費大量的處理器資源
與線程阻塞相比,自旋會浪費大量的處理器資源。這是因為當前線程仍處于運行狀況,只不過跑的是無用指令。它
期望在運行無用指令的過程中,鎖能夠被釋放出來。JVM給出的方案是自適應自旋,根據以往自旋等待時能否獲取鎖,來動態調整自旋的時間。

3、公平性問題
自旋狀態還帶來另外一個副作用,不公平的鎖機制。處于阻塞狀態的線程,無法立刻競爭被釋放的鎖。然而,處于
自旋狀態的線程,則很有可能優先獲得這把鎖。內建鎖無法實現公平機制,而lock體系可以實現公平鎖。

解決ABA問題

在JDK1.5后的atomic包中提供 了AtomicStampedReference來解決ABA問題, 它通過包裝[E,Integer]的元組來對對象標記版本stamp,從而避免ABA問題。在了解AtomicStampedReference之前我們可以先分析一下AtomicReference。

import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceDemo {
public static void main(String[] args) {
AtomicReference<String> atomicReference = new AtomicReference<>();
atomicReference.set("AAA");

//CAS操作更新
boolean result = atomicReference.compareAndSet("AAA", "BBB");
System.out.println(result + " " + atomicReference.get());

//CAS操作更新
result = atomicReference.compareAndSet("AAA", "CCC");
System.out.println(result + " " + atomicReference.get());
}
}

AtomicReference的成員變量

//Unsafe類提供CAS操作
private static final Unsafe unsafe = Unsafe.getUnsafe();

//value變量的偏移地址,這個偏移地址在static塊里初始化
private static final long valueOffset;

//實際傳入需要原子操作的那個類實例
private volatile V value;

compareAndSet方法是基于Unsafe提供的compareAndSwapObject方法, 這里的compareAndSet方法即CAS操作本身是原子的,但是在某些場景下會出現異常場景,也就是ABA問題。我們使用AtomicStampedReference來解決這個問題,下面是AtomicStampedReference的關鍵結構:

public class AtomicStampedReference<V> {
private static class Pair<T> {
final T reference; //維護對象引用
final int stamp; //用于標志版本

private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}

static <T> Pair<T> of(T reference, int stamp) {
return new Pair<T>(reference, stamp);
}
}

private volatile Pair<V> pair;
...
}

謝謝你請我喝咖啡

支付寶 微信
  • 本文作者: Tim
  • 本文鏈接: https://zouchanglin.cn/2020/04/02/892077598.html
  • 版權聲明: 本博客所有文章除特別聲明外,均采用 CC BY-SA 4.0 許可協議。轉載請注明出處!

總結

以上是生活随笔為你收集整理的CAS操作与ABA问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: www在线播放 | 欧美日韩国产一级片 | 日本xxxx裸体xxxx | 欧洲在线一区 | 国产亚洲成av人在线观看导航 | 国产欧美久久久精品免费 | 豆国产97在线 | 亚洲 | 欧美成人xxxx | 国产成人一级片 | 看片网址国产福利av中文字幕 | 韩国三级做爰视频 | 91久久久久久久 | 色站综合 | 少妇与公做了夜伦理 | 久久这里只有 | 手机看片亚洲 | 三上悠亚中文字幕在线播放 | 成人区精品一区二区婷婷 | 初尝人妻少妇中文字幕 | 六月婷婷在线 | 91福利区 | 精品中文字幕视频 | 色综合久久88色综合天天6 | 国产后入又长又硬 | 亚洲毛片网站 | 麻豆高清免费国产一区 | 日本三级免费看 | 日日夜夜免费视频 | 日日夜夜精品视频免费 | 四虎视频 | 生活片av | 午夜视频免费在线 | 91成人国产综合久久精品 | 女人下面喷水视频 | 日本在线不卡一区 | 午夜免费影院 | av在线成人| 明日叶三叶 | 欧美日韩中字 | 国产精品二区一区二区aⅴ污介绍 | 射综合网| 国产亚洲精品久久久久久久久动漫 | 人妻熟女一区二区三区app下载 | www成人啪啪18软件 | 俺来也俺也啪www色 欧洲一区二区视频 | 亚洲美女一区二区三区 | 一本久久精品一区二区 | 天天干天天操天天爽 | 狠狠躁夜夜| 国产欧美久久久精品免费 | 特黄三级 | 91尤物视频在线观看 | 欧美区二区三区 | 韩国视频一区二区 | 中文字幕第100页 | 精品久久久久久久久久久久久久久久久 | 夜久久 | a v免费视频 | 欧美毛片基地 | 男女免费看 | 蘑菇视频黄色 | 四虎新网站 | 中文字幕在线观看线人 | 精品熟女一区 | 国产成人综合一区二区三区 | 国产怡红院 | 欧美激情一区 | 97超碰在线播放 | 国产精品高潮呻吟久久久 | 好av在线| 黑人极品videos精品欧美裸 | 国产卡一卡二卡三无线乱码新区 | 色老头一区二区三区 | 欧美情趣视频 | 国产亚洲欧美日韩精品 | 国产50页| 国产99久久久国产精品成人免费 | 国产在成人精品线拍偷自揄拍 | 91成人免费在线观看视频 | 日本特级黄色录像 | 久久久久久成人 | 青青操国产视频 | 日韩激情四射 | 男女免费视频网站 | 91桃色免费视频 | 黄色网炮 | 精品人妻一区二区三区久久 | 国产又粗又大又爽 | 丝袜美腿一区二区三区 | 中日韩免费毛片 | 波多野结衣调教 | 狠狠影院 | 97精品| 亚洲天堂99 | 2021狠狠干| 午夜极品视频 | jizz自拍| 日韩欧美视频一区 | 大尺度一区二区 |