最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

CAS是什么?

2023-06-29 21:16 作者:紅紅的2  | 我要投稿

CAS(Compare And Swap)是一種用于實現(xiàn)無鎖并發(fā)算法的技術(shù)。

大多數(shù)時候它也還有其他叫法:無鎖優(yōu)化、自旋、樂觀鎖

它的核心思想是:通過比較當(dāng)前需要修改的值與預(yù)期原來的值,如果相等,則使用新值進行替換。

這個過程是原子性的,它底層是靠C語言依賴的操作系統(tǒng)的原子操作來保證原子性的,即在這個過程中不會被其他線程打斷。

在Java中,CAS操作主要是通過?java.util.concurrent.atomic包中的原子類來實現(xiàn)的,如?AtomicInteger、AtomicLong等。

原理示例

假設(shè)有一個整數(shù)變量?count,初始值為0?,F(xiàn)在有兩個線程A和B同時對?count進行加1操作。使用CAS操作可以確保?count最終的值為2。

java面試大全:kdocs.cn/l/cfoqiIIJ4xmW

  1. 線程A讀取?count的值,得到0。

  2. 線程B讀取?count的值,得到0。

  3. 線程A將?count的值與預(yù)期值0進行比較,相等,則將?count的值更新為1。

  4. 線程B將?count的值與預(yù)期值0進行比較,不相等(因為已經(jīng)被線程A更新為1),則重試。

  5. 線程B重新讀取?count的值,得到1。

  6. 線程B將?count的值與預(yù)期值1進行比較,相等,則將?count的值更新為2。

最終,count的值為2,實現(xiàn)了無鎖并發(fā)操作。

二、源碼分析

以?java.util.concurrent.atomic.AtomicInteger為例,這個類提供了一個原子的整數(shù)值,可以用于實現(xiàn)無鎖的整數(shù)操作。我們來看一下它的?compareAndSet方法的源碼:

public final boolean compareAndSet(int expect, int update){ return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }

這里的?unsafe是一個?sun.misc.Unsafe類型的對象,它提供了底層的CAS操作。valueOffset是一個靜態(tài)常量,表示?AtomicInteger內(nèi)部的?value字段的內(nèi)存偏移量。expect是預(yù)期值,update是新值。這個方法會返回一個布爾值,表示操作是否成功。

小結(jié):

atomicXXX類

  • Compare and Set/Swap 比較并且設(shè)定

  • cas(V,Expected,NewValue)

if V == EV == New otherwise try again or fail

  • CPU原語支持 atomic底層調(diào)用到UnSafe這個方法,三個參數(shù)V就是當(dāng)前版本值,Expected期望值,NewValue賦予的新值。
    只有當(dāng)V等于E的時候才將新的值賦給這個變量,又因為它是原語支持是CPU級別的,是一個原子操作,所以在設(shè)值時不會有其他線程來插隊設(shè)值。

三、實戰(zhàn)應(yīng)用

我們來看一個實際的例子,如何使用?AtomicInteger實現(xiàn)一個無鎖的計數(shù)器。

public class Counter { ? ?/*volatile*/ //int count1 = 0; ? ?AtomicInteger count = new AtomicInteger(0); ? ?/*synchronized*/ void m() { ? ? ? ?for (int i = 0; i < 10000; i++) ? ? ? ? ? ?//if count1.get() < 1000 ? ? ? ? ? ?count.incrementAndGet(); //count1++ ? ?} ? ?public static void main(String[] args) { ? ? ? ?Counter t = new Counter(); ? ? ? ?List<Thread> threads = new ArrayList<Thread>(); ? ? ? ?for (int i = 0; i < 10; i++) { ? ? ? ? ? ?threads.add(new Thread(t::m, "thread-" + i)); ? ? ? ?} ? ? ? ?threads.forEach((o) -> o.start()); ? ? ? ?threads.forEach((o) -> { ? ? ? ? ? ?try { ? ? ? ? ? ? ? ?o.join(); ? ? ? ? ? ?} catch (InterruptedException e) { ? ? ? ? ? ? ? ?e.printStackTrace(); ? ? ? ? ? ?} ? ? ? ?}); ? ? ? ?System.out.println(t.count); ? ?} }


編輯搜圖

在這個例子中,我們創(chuàng)建了一個?Counter類,內(nèi)部使用?AtomicInteger實現(xiàn)了無鎖的計數(shù),然后我們創(chuàng)建了10個線程,分別對計數(shù)器進行增加操作。最后我們輸出計數(shù)器的值,可以看到它確實是10000,證明我們的無鎖計數(shù)器是正確的。

四、CAS在日常中的應(yīng)用場景

在實際開發(fā)中,我們可能會遇到以下幾種使用CAS的場景:

  1. 無鎖計數(shù)器?:如上面的例子所示,我們可以使用CAS實現(xiàn)一個高效的無鎖計數(shù)器,避免了使用同步鎖帶來的性能開銷。

  2. 單例模式?:我們可以使用CAS實現(xiàn)一種線程安全的單例模式,確保在多線程環(huán)境下只創(chuàng)建一個實例。

  3. 并發(fā)容器?:在實現(xiàn)高性能的并發(fā)容器時,如?ConcurrentHashMap,我們可以使用CAS操作來實現(xiàn)無鎖或低鎖的數(shù)據(jù)結(jié)構(gòu)更新。

  4. 多線程并發(fā)任務(wù)?:在多線程并發(fā)執(zhí)行任務(wù)時,我們可以使用CAS操作來確保任務(wù)狀態(tài)的正確更新,例如實現(xiàn)一個無鎖的任務(wù)分發(fā)器。

五、ABA問題

如果另一個線程修改V值,假設(shè)原來是A,先修改成B,再修改回成A。

當(dāng)前線程的CAS操作無法分辨當(dāng)前V值是否發(fā)生過變化,這個就是ABA問題。

解決:

  • 在CAS的時候加版本號,每次操作比較下版本號

  • 加 version

  • A 1.0

  • B 2.0

  • A 3.0

  • cas(version)

  • 原子類 AtomicStampedReference解決ABA問題

  • ABA問題重要不?如果是基本數(shù)據(jù)類型結(jié)果沒影響,如果是引用對象就不好說了,比如你的女朋友和你復(fù)合,前面經(jīng)過了多少個其他XXX,你覺得有影響不?

面試大全超級詳細?。?/p>


java面試大全:


搜索公眾號回復(fù)eee003獲取


CAS是什么?的評論 (共 條)

分享到微博請遵守國家法律
南汇区| 怀安县| 于都县| 临清市| 丰宁| 万荣县| 甘洛县| 吉安县| 湘阴县| 乐清市| 葫芦岛市| 调兵山市| 固阳县| 阳东县| 宝应县| 永仁县| 石嘴山市| 潼南县| 永兴县| 仲巴县| 汉中市| 宁南县| 康马县| 手游| 北海市| 丰城市| 华池县| 会东县| 汝南县| 牡丹江市| 类乌齐县| 阿勒泰市| 岳池县| 阿拉善盟| 金平| 文安县| 封开县| 金乡县| 佛坪县| 清镇市| 田林县|