Java CAS 的原子操作实现
Jakcy
Java
2021-10-09
23
CAS原理
修改内存中的某一个值V,提供一个旧值A和一个新值B。如果提供的旧值V和A相等就把B写入V。这个过程是原子性的。CAS执行结果要么成功要么失败,对于失败的情形下,采用不断重试直至修改成功或者直接放弃修改。
代码实现
package com.dome.test;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class CASCounter {
private int value=0;
private static final sun.misc.Unsafe UNSAFE;
private static final long nextOffset;
static {
try {
UNSAFE = getUnsafe();
Class<?> k = CASCounter.class;
// 获取字段相对Java对象的“起始地址”的偏移量
// 可通过getInt、getLong、getObject之类的方法可以使用前面获取的偏移量来访问对象的字段
nextOffset = UNSAFE.objectFieldOffset (k.getDeclaredField("value"));
} catch (Exception e) {
throw new Error(e);
}
}
private static Unsafe getUnsafe() {
try {
return Unsafe.getUnsafe();
} catch (SecurityException se) {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(Unsafe.class);
} catch (Exception e) {
throw new RuntimeException("exception while trying to get Unsafe", e);
}
}
}
/**
* 1,基于sun.misc.Unsafe实现
*/
public boolean compareAndSwapInt1(int oldValue, int newValue) {
return UNSAFE.compareAndSwapInt(this,nextOffset,oldValue,newValue);
}
/**
* 2,基于同步块实现
*/
public boolean compareAndSwapInt2(int oldValue, int newValue) {
synchronized (this) {
if (value == oldValue) {
value = newValue;
return true;
} else {
return false;
}
}
}
public int index() {
int oldvalue;
do {
oldvalue = value;
} while (!compareAndSwapInt1(oldvalue, oldvalue + 1));
return oldvalue + 1;
}
public int getValue(){
return UNSAFE.getInt(this,nextOffset);
}
}