Java Unsafe類 CAS簡單使用實現自旋鎖
阿新 • • 發佈:2020-07-20
自己實現了一個類似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例項可能會造成執行緒不安全)。