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);
}
}
运行结果: