簡述java中cas
cas原理
cas是compareAndSwap的縮寫,可以看出就是比較比替換的意思。cas中有三個值,記憶體值V,舊的預期值E,更新值U,當且僅當V==E時,才進行更新,否則返回V。
cas應用
以java.util.concurrent包中的AtomicInteger為例。先演示程式碼:
public class AtomicIntegerTest {
private static AtomicInteger atomicInteger=new AtomicInteger(5);//設定初始值
public static void main(String[] args) {
atomicInteger.compareAndSet(0,1);//0!=5,不變
atomicInteger.compareAndSet(2,3);//2!=5,不變
atomicInteger.compareAndSet(3,4);//3!=5,不變
atomicInteger.compareAndSet(5,2);//5==5,更新為2
atomicInteger.compareAndSet(0,4);//0!=2,不變
System.out.println("result:"+atomicInteger.get());
}
}
輸出結果是:result:2
原始碼:
/**使用 Unsafe.compareAndSwapInt()進行更新*/
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
/**靜態程式碼塊對valueOffset進行初始化*/
static {
try {
valueOffset = unsafe.objectFieldOffset
(java.util.concurrent.atomic.AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
/**使用volatile修飾value,保證value值的一致性*/
private volatile int value;
/**
* 有參構構造方法
*/
public AtomicInteger(int initialValue) {
value = initialValue;
}
/**
* 無參構造方法
*/
public AtomicInteger() {
}
/**
* 獲取值
*/
public final int get() {
return value;
}
/**
* 設定值
*/
public final void set(int newValue) {
value = newValue;
}
/**
* 最終設定為給定值。
*/
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}
/**
* 原子地設定為給定值並返回舊值。
*
*/
public final int getAndSet(int newValue) {
return unsafe.getAndSetInt(this, valueOffset, newValue);
}
/**
*
* 若當前值等於期望的值,則更新給定的更新值
*
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
*自增1
*
*/
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
/**
* 自減1
*
*/
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
/**
* 增加給定的值
*
*/
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}
/**
* 更新並返回原先的值
*/
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}
/**
* 返回更新之後的值
*/
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}
原子包還有以下,用法基本一樣。
cas中的ABA問題
CAS可以有效的提升併發的效率,但同時也會引入ABA問題。
如執行緒1從記憶體X中取出A,這時候另一個執行緒2也從記憶體X中取出A,並且執行緒2進行了一些操作將記憶體X中的值變成了B,然後執行緒2又將記憶體X中的資料變成A,這時候執行緒1進行CAS操作發現記憶體X中仍然是A,然後執行緒1操作成功。雖然執行緒1的CAS操作成功,但是整個過程就是有問題的。比如連結串列的頭在變化了兩次後恢復了原值,但是不代表連結串列就沒有變化。
所以JAVA中提供了AtomicStampedReference/AtomicMarkableReference來處理會發生ABA問題的場景,主要是在物件中額外再增加一個標記來標識物件是否有過變更。
相關文章
- Java代理簡述Java
- java併發簡述Java
- Java入門簡述(3)Java
- Java SPI機制簡述Java
- Java 8 中 CAS 的增強Java
- Android中的ANR簡述Android
- Java CAS 原理詳解Java
- Dojo簡述
- CNN 簡述CNN
- CAS原子操作以及其在Java中的應用Java
- 【Java】【多執行緒】執行緒池簡述Java執行緒
- CAS單點登入-簡介
- Java中的鎖原理、鎖優化、CAS、AQS詳解!Java優化AQS
- 文字摘要簡述
- Angular框架簡述Angular框架
- CMN簡述 --20240305
- 轉移簡述
- DES加密簡述加密
- Spring MVC 簡述SpringMVC
- ViT簡述【Transformer】ORM
- Web 開發中 Blob 與 FileAPI 使用簡述WebAPI
- Android Studio中引入Gson依賴(簡述版)Android
- java高併發系列 - 第21天:java中的CAS操作,java併發的基石Java
- CAS學習筆記一:CAS 授權伺服器簡易搭建筆記伺服器
- 好程式設計師Java培訓簡述Java新手如何學程式碼程式設計師Java
- Java併發(4)- synchronized與CASJavasynchronized
- Java多執行緒之CASJava執行緒
- Java併發程式設計-CASJava程式設計
- HTTP協議簡述HTTP協議
- Linux 核心、Shell 簡述Linux
- Kubernetes架構簡述架構
- 簡述Linux磁碟IOLinux
- Symfony 路由配置簡述路由
- 新特性 Hook 簡述Hook
- 簡述HTTP協議HTTP協議
- 密碼學簡述密碼學
- 簡述LSM-Tree
- 簡述Web3.0Web