日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

每日一博 - CAS(Compare-And-Swap)原理剖析

發(fā)布時(shí)間:2025/3/21 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每日一博 - CAS(Compare-And-Swap)原理剖析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • What's CAS & sun.misc.Unsafe
  • CAS & sun.misc.Unsafe
  • 以AtomicInteger為例底層原理剖析
  • CAS缺點(diǎn)
  • ABA 問(wèn)題


What’s CAS & sun.misc.Unsafe

全稱(chēng) Compare-And-Swap , 主要實(shí)現(xiàn)的功能是和內(nèi)存中的某個(gè)位置的值進(jìn)行比較判斷是否為預(yù)期值,如果是預(yù)期值則更改為新值, 整個(gè)過(guò)程具有原子性。


CAS & sun.misc.Unsafe

CAS屬于CPU并發(fā)原語(yǔ)

CAS是一種系統(tǒng)原語(yǔ),原語(yǔ)屬于操作系統(tǒng)應(yīng)用范疇,是由若干條指令組成,用于完成某個(gè)功能的一個(gè)過(guò)程,并且原語(yǔ)的執(zhí)行必須是連續(xù)的,在執(zhí)行過(guò)程中不允許被中斷,也就是說(shuō)CAS是一條CPU的原子指令,不會(huì)造成所謂的數(shù)據(jù)不一致的問(wèn)題,即CAS是線程安全的

在JDK中,主要體現(xiàn)在sun.misc.Unsafe類(lèi)。

當(dāng)執(zhí)行UnSafe類(lèi)中的cas相關(guān)方法時(shí), JVM會(huì)轉(zhuǎn)換成類(lèi)似匯編指令,通過(guò)它實(shí)現(xiàn)了原子操作。

來(lái)看個(gè)代碼

package com.artisan.juc;import java.util.concurrent.atomic.AtomicInteger;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/11/6 13:11* @mark: show me the code , change the world*/ public class CASTest {public static void main(String[] args) {// 設(shè)置初始值為100AtomicInteger atomicInteger = new AtomicInteger(100);// 使用atomicInteger的compareAndSet,如果為100,則更新為123boolean b = atomicInteger.compareAndSet(100, 123);System.out.println(b + "----" + atomicInteger.get());// 使用atomicInteger的compareAndSet,如果為100,則更新為456 (上一步已經(jīng)更新成了123,所以不是100)b = atomicInteger.compareAndSet(100, 456);System.out.println(b + "----" + atomicInteger.get());} }

輸出

true----123 false----123


以AtomicInteger為例底層原理剖析

繼續(xù)在上個(gè)例子的基礎(chǔ)上,完善一下,方便引入知識(shí)點(diǎn),增加紅框內(nèi)如下代碼:

輸出

我們來(lái)分析下 getAndIncrement

先看看 AtomicInteger類(lèi)


看方法的注釋說(shuō)明: 以原子的方式在當(dāng)前值的基礎(chǔ)上加1 ,返回的是加1之前的值。

可以看到其實(shí)是調(diào)用了unsafe# getAndAddInt

那先看看Unsafe類(lèi) 唄


內(nèi)部方法操作可以像C的指針一樣直接操作內(nèi)存

Unsafe位于sun.misc包中,該類(lèi)的方法都是native的本地方法 ,這也意味著unsafe類(lèi)中的方法都直接調(diào)用操作系統(tǒng)底層資源執(zhí)行相應(yīng)的任務(wù)。

Unsafe類(lèi)是CAS的核心類(lèi). 我們知道Java無(wú)法直接訪問(wèn)底層操作系統(tǒng),需要通過(guò)native方法來(lái)實(shí)現(xiàn)。 Unsafe這個(gè)魔法類(lèi)可以理解為一個(gè)后門(mén),通過(guò)該類(lèi)可以直接操作特定的內(nèi)存數(shù)據(jù)。


繼續(xù)【getAndAddInt方法 】


  • var1: AtomicInteger本對(duì)象

  • var2: 該對(duì)象值得引用地址

  • var4: 需要變動(dòng)的數(shù)量

  • var5: var5 = this.getIntVolatile(var1, var2); 從主內(nèi)存中拿到的值 , 如果當(dāng)前值和期望值一樣,就執(zhí)行 var5 + var4 . (用var1和var2找到的內(nèi)存中的真實(shí)值用該對(duì)象當(dāng)前的值與var5比較)

do while 循環(huán) , 如果compareAndSwapInt返回false,那么就一直執(zhí)行 while方法,直到期望的值和真實(shí)值一樣

CAS有3個(gè)操作數(shù),內(nèi)存值V,舊的預(yù)期值,要修改的更新值。當(dāng)且僅當(dāng)預(yù)期值和內(nèi)存值相同時(shí),將內(nèi)存值修改為更新值,否則不操作 .


CAS缺點(diǎn)

CAS不加鎖,保證一致性,但是需要多次比較

  • 對(duì)于多個(gè)共享變量操作時(shí),循環(huán)CAS就無(wú)法保證操作的原子性,這個(gè)時(shí)候只能用鎖來(lái)保證原子性

  • 循環(huán)時(shí)間長(zhǎng),開(kāi)銷(xiāo)大(因?yàn)閳?zhí)行的是do while,如果比較不成功一直在循環(huán),最差的情況,就是某個(gè)線程一直取到的值和預(yù)期值都不一樣,這樣就會(huì)無(wú)限循環(huán))

  • 只能保證一個(gè)共享變量的原子操作,當(dāng)對(duì)一個(gè)共享變量執(zhí)行操作時(shí),我們可以通過(guò)循環(huán)CAS的方式來(lái)保證原子操作


ABA 問(wèn)題

如果一個(gè)變量初次讀取的時(shí)候是 A 值,它的值被改成了 B,后來(lái)又被改回為 A,那 CAS 操作就會(huì)誤認(rèn)為它從來(lái)沒(méi)有被改變過(guò)。

總結(jié)

以上是生活随笔為你收集整理的每日一博 - CAS(Compare-And-Swap)原理剖析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。