竞态条件与临界区
共享资源
不可变对象
原子操作定义
- 原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分(不可中断性)。
- 将整个操作视作一个整体,资源在该次操作中保持一致,这是原子性的核心特征。
CAS机制
volatile int value = 0;
static Unsafe unsafe;
private static long valueOffset;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
valueOffset = unsafe.objectFieldOffset(LockDemo1.class
.getDeclaredField("value"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void add() {
int current;
do {
current = unsafe.getIntVolatile(this, valueOffset);
} while (!unsafe.compareAndSwapInt(this, valueOffset, current, current + 1));
}
复制代码
- 有兴趣的童鞋可以了解下Unsafe的源码,类似于直接操作内存的方法。JVM调用系统本地方法操作数据,保证只有一个线程可以访问到本地方法操作,实现原子操作。
J.U.C包内的原子操作封装类
- java.until.concurrent线程工具类(J.U.C)
CAS的三个问题
- JAVA提供了ABA的解决办法:原子更新带有版本号的引用类型。CAS在比对是不仅比对值,还会比对版本号。
- Atomic原子操作封装类,将i++分成了几步(读取值,更新值,赋值),使用了底层的CAS机制,并且不仅仅存了值,还存了时间戳版本号。