CAS
本文介绍CAS、通过案例去演示CAS、CAS的应用场景、如何利用CAS进行原子操作、CAS的缺点。
概述
CAS是一种思想,使用并发场景,是一种原子性的操作,实现不能被其他线程打断的情况。
思路:我认为他应该是A,如果是我就修改,如果不是我就放弃他,可以避免多人修改引发的问题。
具体参数:内存值、预期值、修改值,只有当内存值和预期值相等的时候,才会去修改;利用CPU的指令保证他的原子性。
代码示例
两个线程都去修改公共变量,只有一个可以修改成功,示例代码如下所示。
package com.yang.cas;
import javax.management.relation.RoleUnresolved;
/**
* 模拟CAS操作
*/
public class SimulatedCASDemo implements Runnable {
private volatile int value;
public synchronized int compareAndSwap(int expectedValue, int newValue) {
int oldValue = value;
if (oldValue == expectedValue) {
value = newValue;
}
return value;
}
@Override
public void run() {
compareAndSwap(0, 1);
}
/**
* 两个线程都去修改参数,只有个线程可以修改成功
* 最终的输出结果为1
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
SimulatedCASDemo simulatedCASDemo=new SimulatedCASDemo();
Thread thread1=new Thread(simulatedCASDemo);
Thread thread2=new Thread(simulatedCASDemo);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(simulatedCASDemo.value);
}
}
应用场景
乐观锁
并发容器:concurrentHashMap
原子类
原子类如何实现CAS
原子类AtomicInteger加载unsafe工具,用来直接操作内存数据;用volatile 修饰value字段,保证可见性。
Unsafe可以拿到内存地址,部分代码如下所示:
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
.........................
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缺点
1.ABA问题:先修改为A,再修改为B,再修改为A,检查和我的值是否相等,乐观锁可以加个版本号
2.自旋时间较长

浙公网安备 33010602011771号