深入理解CAS
什么是CAS
為什么要學(xué)CAS:大廠你必須深入研究底層!有所突破!
java層面的cas------->compareAndSet
compareAndSet(int expectedValue, int newValue) 期望并更新,達到期望值就更新、否則就不更新!
package org.example.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
//JAVA CAS -> 比較并交換
//期望、更新
//compareAndSet(int expectedValue, int newValue)
//如果我期望的值達到了那么就跟新、否則就不更新;CAS 是CPU的并發(fā)原語!
System.out.println(atomicInteger.compareAndSet(2020, 2021));
//達到期望值更新成功
System.out.println(atomicInteger.get());
//更新后未達到期望值,更新失敗
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
}
}
Unsafe類
java不能直接操作內(nèi)存,但是可以調(diào)用c++,c++可以操作內(nèi)存,java可以通過native關(guān)鍵字定義的方法來調(diào)用c++。Unsafe類就像是java留給自己的一個后門。所以Unsafe類中都是native方法和調(diào)用native方法的方法!
在原子類里,有一個getAndIncrement方法用作自增、那么他的底層是如何實現(xiàn)的呢?
其實就是調(diào)用的unsafe類中的getAndAddInt方法
public final int getAndIncrement() {
//dalta傳入了1
return U.getAndAddInt(this, VALUE, 1);
}
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
//v每次都跟新為最新值,所以一直會是期望的值!就執(zhí)行了++的操作
v = getIntVolatile(o, offset);
//如果當(dāng)前對象o期望的值等于v,那么將當(dāng)前對象o的值跟新為v+dalta;
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
return v;
}
public final boolean weakCompareAndSetInt(Object o, long offset,
int expected,
int x) {
return compareAndSetInt(o, offset, expected, x);
}
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);
對比觀察,其實getAndAddInt就是定義一個變量取到最新的值,然后通過while循環(huán)一直更新,其中g(shù)etIntVolatile和compareAndSetInt都是通過java調(diào)用底層c++操作內(nèi)存。
其中用到了一段標(biāo)準(zhǔn)的鎖(自旋鎖!):
do {
//v每次都跟新為最新值,所以一直會是期望的值!就執(zhí)行了++的操作
v = getIntVolatile(o, offset);
//如果當(dāng)前對象o期望的值等于v,那么將當(dāng)前對象o的值跟新為v+dalta;
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
缺點
1、循環(huán)會耗時
2、一次性只能保證一個共享變量的原子性
3、會存在ABA問題
優(yōu)點
自帶原子性
CAS : ABA問題(貍貓換太子)!文章來源:http://www.zghlxwxcb.cn/news/detail-750313.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-750313.html
package org.example.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
//JAVA CAS -> 比較并交換
//期望、更新
//compareAndSet(int expectedValue, int newValue)
//如果我期望的值達到了那么就跟新、否則就不更新; CAS 是CPU的并發(fā)原語!
//===============搗亂的線程================
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.compareAndSet(2021, 2020));
//達到期望值更新成功
System.out.println(atomicInteger.get());
//更新后未達到期望值,更新失敗
//===============期望的線程================
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
//getAndIncrement number++ 底層如何實現(xiàn)的?
atomicInteger.getAndIncrement();//++方法
}
}
到了這里,關(guān)于JUC并發(fā)編程學(xué)習(xí)筆記(十八)深入理解CAS的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!