public class UseUnsafeClassDemo {
static Unsafe unsafe = Unsafe.getUnsafe();
private static long offset;
private static volatile int state = 0;
static {
try {
offset = unsafe.objectFieldOffset(UseUnsafeClassDemo.class.getField("state"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
UseUnsafeClassDemo useUnsafeClassDemo = new UseUnsafeClassDemo();
boolean result = unsafe.compareAndSwapInt(useUnsafeClassDemo, offset, state, 1);
System.out.println(result);
}
}
運行結果:
報錯原因:
當前應用使用AppClassLoader是無法獲取Unsafe實例的,這是jvm出於安全考慮,只能由Bootstrap類加載器加載。
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
// 判斷是否爲BootstrapClassLoader
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
利用反射獲取
/**
* 利用反射獲取Unsafe
*/
public class ReflectUnsafeClassDemo {
static Unsafe unsafe = null;
static long offset = 0;
private volatile int state = 0;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
offset = unsafe.objectFieldOffset(ReflectUnsafeClassDemo.class.getDeclaredField("state"));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ReflectUnsafeClassDemo useUnsafeClassDemo = new ReflectUnsafeClassDemo();
boolean result = unsafe.compareAndSwapInt(useUnsafeClassDemo, offset, 0, 1);
System.out.println(result);
}
}
運行結果: