自己实现了一个类似AtomicInteger的原子类功能,反复比较并交换,主要用到
- 反射获取Unsafe及对象的静态成员变量
- Unsafe获取地址偏移量
- CAS
public class MyStudy {
public static int data = 0;
public static void main(String[] args) throws Exception{
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
long dataAddress = unsafe.staticFieldOffset(MyStudy.class.getDeclaredField("data"));
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 100; j++) {
int anInt = unsafe.getInt(MyStudy.class, dataAddress);
while(!unsafe.compareAndSwapInt(MyStudy.class,dataAddress,anInt,anInt+1))
anInt = unsafe.getInt(MyStudy.class, dataAddress);
}
}
}).start();
}
Thread.sleep(1000);
System.out.println(data);
}
}
运行结果10000。
Unsafe类需要使用获取其静态成员变量的方法来拿到,调用getUnsafe()会报错,反射拿取构造函数就违背了Unsafe的初衷(多个Unsafe实例可能会造成线程不安全)。