当前位置:网站首页>CAS操作
CAS操作
2022-07-25 07:54:00 【季风泯灭的季节】
什么是 CAS
if (value == expectedValue) {
value = newValue;
}public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);
public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);
public final native boolean compareAndSwapLong(Object o, long offset, long expected, long x);public class UnsafeFactory {
/**
* 获取 Unsafe 对象 * @return
*/
public static Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取字段的内存偏移量
* @param unsafe
* @param clazz
* @param fieldName
* @return
*/
public static long getFieldOffset(Unsafe unsafe, Class clazz, String fieldNam e) {
try {
return unsafe.objectFieldOffset(clazz.getDeclaredField(fieldName));
} catch (NoSuchFieldException e) {
throw new Error(e);
}
}
}
CAS 本质是一条CPU 的原子指令,由操作系统硬件来保证。不同操作系统和不同CPU会有不同的 实现。
CAS 在 Java 语言中的应用
在 Java 编程中我们通常不会直接使用到 CAS,都是通过 JDK 封装好的并发工具类来间接使用的,这些并发工具类都在java.util.concurrent包中。
J.U.C 是
java.util.concurrent的简称,也就是大家常说的 Java 并发编程工具包,面试常考,非常非常重要。
- 基本类型:AtomicInteger、AtomicLong、AtomicBoolean;
- 引用类型:AtomicReference、AtomicStampedRerence、AtomicMarkableReference;
- 数组类型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
- 对象属性原子修改器:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater
- 原子类型累加器(jdk1.8增加的类):DoubleAccumulator、DoubleAdder、 LongAccumulator、LongAdder、Striped64
//以原子的方式将实例中的原值加1,返回的是自增前的旧值;
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//getAndSet(int newValue):将实例中的值更新为新值,并返回旧值; 、
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
//incrementAndGet() :以原子的方式将实例中的原值进行加1操作,并返回最终相加后的结果;
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
//addAndGet(int delta) :以原子方式将输入的数值与实例中原本的值相加,并返回最后的结 果;
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}测试
public class AtomicIntegerTest {
static AtomicInteger sum = new AtomicInteger(0);
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() ->{
for (int j = 0; j < 10000; j++) {
// 原子自增 CAS
sum.incrementAndGet();
}
}).start();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(sum.get());
}
}public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}CAS缺陷
- 自旋 CAS 长时间地不成功,则会给 CPU 带来非常大的开销
- 只能保证一个共享变量原子操作
- ABA 问题
LongAdder/DoubleAdder
LongAccumulator

public static void main(String[] args) throws InterruptedException {
// 累加 x+y
LongAccumulator accumulator = new LongAccumulator((x, y) -> x + y, 0);
ExecutorService executor = Executors.newFixedThreadPool(8);
// 1到9累加
IntStream.range(1, 10).forEach(i -> executor.submit(() -> accumulator.accumulate(i)));
Thread.sleep(2000);
System.out.println(accumulator.getThenReset());
}ABA问题的解决方案
Java提供了相应的原子引用类AtomicStampedReference<V>;reference即我们实际存储的变量,stamp是版本,每次修改可以通过+1保证版本唯一性。这样就可以保证每次修改后的版本也会往上递增。


边栏推荐
- Quickly build a centralized logging platform through elk
- 2-6. Automatic acquisition
- Native form submission data
- 机器学习入门详解(一):理解监督学习中的最大似然估计
- pom容易忽略的问题
- Gan series of confrontation generation network -- Gan principle and small case of handwritten digit generation
- [recommended reading] a collection of super useful vulnerability scanning tools!
- Oracle19 adopts automatic memory management. The AWR report shows that the settings of SGA and PGA are too small?
- Load capacity - sorting out the mind map that affects load capacity
- webflux默认io线程数
猜你喜欢

深度学习之快速实现数据集增强的方法

交叉熵计算公式

In depth analysis of yolov7 network architecture

【Unity入门计划】界面介绍(2)-Games视图&Hierarchy&Project&Inspector
![[unity introduction program] basic concept - preform prefab](/img/c6/aac7bffdf99073978f9b2f8ff15fbb.png)
[unity introduction program] basic concept - preform prefab

Leetcode (Sword finger offer) - 04. search in two-dimensional array
![[paper notes] effective CNN architecture design guided by visualization](/img/aa/aeeac3f970eac7f110987c523602c8.png)
[paper notes] effective CNN architecture design guided by visualization

Use cyclegan to train self-made data sets, popular tutorials, and get started quickly

Introduction to Manhattan distance

The two Nobel Prize winners became the chief scientist of the sky high price Baijiu of "taishanglaojun holding a dream"
随机推荐
纳米数据足球数据,足球赛事比分,体育数据api,卡塔尔世界杯
Problems during nanodet training: modulenotfounderror: no module named 'nanodet' solution
C# 43. 获取UDP可用端口
How to do a good job in safety development?
[unity introduction plan] interface Introduction (2) -games view & hierarchy & Project & Inspector
文件详细操作
What has become a difficult problem for most people to change careers, so why do many people study software testing?
J1 common DOS commands (P25)
Design of workflow system
Use cyclegan to train self-made data sets, popular tutorials, and get started quickly
Nano data, football data, football match scores, sports data API, Qatar world cup
Today in history: Intel was founded; The first photo was posted on the world wide web; EBay spins off PayPal
Redis client tool redis insight recommendation
How does MTK change the boot logo?
Kubernetes monitoring component metrics server deployment
[QNX Hypervisor 2.2用户手册]9.3 cpu
设计一个有getMin功能的栈
Have you got the advanced usage of pytest?
【论文笔记】Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized
P1046 [noip2005 popularity group t1] Taotao picking apples