每日一博 - CAS(Compare-And-Swap)原理剖析
文章目錄
- What's CAS & sun.misc.Unsafe
- CAS & sun.misc.Unsafe
- 以AtomicInteger為例底層原理剖析
- CAS缺點
- ABA 問題
What’s CAS & sun.misc.Unsafe
全稱 Compare-And-Swap , 主要實現的功能是和內存中的某個位置的值進行比較判斷是否為預期值,如果是預期值則更改為新值, 整個過程具有原子性。
CAS & sun.misc.Unsafe
CAS屬于CPU并發原語
CAS是一種系統原語,原語屬于操作系統應用范疇,是由若干條指令組成,用于完成某個功能的一個過程,并且原語的執行必須是連續的,在執行過程中不允許被中斷,也就是說CAS是一條CPU的原子指令,不會造成所謂的數據不一致的問題,即CAS是線程安全的
在JDK中,主要體現在sun.misc.Unsafe類。
當執行UnSafe類中的cas相關方法時, JVM會轉換成類似匯編指令,通過它實現了原子操作。
來看個代碼
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) {// 設置初始值為100AtomicInteger atomicInteger = new AtomicInteger(100);// 使用atomicInteger的compareAndSet,如果為100,則更新為123boolean b = atomicInteger.compareAndSet(100, 123);System.out.println(b + "----" + atomicInteger.get());// 使用atomicInteger的compareAndSet,如果為100,則更新為456 (上一步已經更新成了123,所以不是100)b = atomicInteger.compareAndSet(100, 456);System.out.println(b + "----" + atomicInteger.get());} }輸出
true----123 false----123以AtomicInteger為例底層原理剖析
繼續在上個例子的基礎上,完善一下,方便引入知識點,增加紅框內如下代碼:
輸出
我們來分析下 getAndIncrement
先看看 AtomicInteger類
看方法的注釋說明: 以原子的方式在當前值的基礎上加1 ,返回的是加1之前的值。
可以看到其實是調用了unsafe# getAndAddInt
那先看看Unsafe類 唄
內部方法操作可以像C的指針一樣直接操作內存
Unsafe位于sun.misc包中,該類的方法都是native的本地方法 ,這也意味著unsafe類中的方法都直接調用操作系統底層資源執行相應的任務。
Unsafe類是CAS的核心類. 我們知道Java無法直接訪問底層操作系統,需要通過native方法來實現。 Unsafe這個魔法類可以理解為一個后門,通過該類可以直接操作特定的內存數據。
繼續【getAndAddInt方法 】
到
到
-
var1: AtomicInteger本對象
-
var2: 該對象值得引用地址
-
var4: 需要變動的數量
-
var5: var5 = this.getIntVolatile(var1, var2); 從主內存中拿到的值 , 如果當前值和期望值一樣,就執行 var5 + var4 . (用var1和var2找到的內存中的真實值用該對象當前的值與var5比較)
do while 循環 , 如果compareAndSwapInt返回false,那么就一直執行 while方法,直到期望的值和真實值一樣
CAS有3個操作數,內存值V,舊的預期值,要修改的更新值。當且僅當預期值和內存值相同時,將內存值修改為更新值,否則不操作 .
CAS缺點
CAS不加鎖,保證一致性,但是需要多次比較
-
對于多個共享變量操作時,循環CAS就無法保證操作的原子性,這個時候只能用鎖來保證原子性
-
循環時間長,開銷大(因為執行的是do while,如果比較不成功一直在循環,最差的情況,就是某個線程一直取到的值和預期值都不一樣,這樣就會無限循環)
-
只能保證一個共享變量的原子操作,當對一個共享變量執行操作時,我們可以通過循環CAS的方式來保證原子操作
ABA 問題
如果一個變量初次讀取的時候是 A 值,它的值被改成了 B,后來又被改回為 A,那 CAS 操作就會誤認為它從來沒有被改變過。
總結
以上是生活随笔為你收集整理的每日一博 - CAS(Compare-And-Swap)原理剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每日一博 - Semaphore使用场景
- 下一篇: 每日一博 - 如何理解跳表(SkipLi