日常写代码很少直接使用到Unsafe,时常看jdk的时候,遇到这个使用场景。刚挑选了一个比较熟悉的CAS来做一个api使用测试。
public class UnsafeTest {
private String name = "a";
private String addr = "b";
private int age = 11;
private int id = 2;
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//Unsafe unsafe = Unsafe.getUnsafe(); //不允许外部使用,会抛异常
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafeInstance.get(Unsafe.class);
long ageOffset = unsafe.objectFieldOffset
(UnsafeTest.class.getDeclaredField("age"));
UnsafeTest unsafeTest = new UnsafeTest();
System.out.println(unsafe.compareAndSwapInt(unsafeTest,ageOffset,11,22));
System.out.println(unsafeTest.age);
}
}
由于Unsafe.getUnsafe()
是不允许外部使用的,会抛出java.lang.SecurityException: Unsafe
异常。所以利用反射获取Unsafe实例。
compareAndSwapInt(Object var1, long var2, int var4, int var5)
有四个参数。
- 第一个是被修改的对象
- 第三个是被修改的属性当前的期望值
- 第四个是计划要修改的值
其实就是,当var1对象的某个属性,值为var4,就修改为var5.这里说了,是某个属性,而第二个参数则是用来标注所需要修改的属性的offset了。
通俗来讲,就是offset偏移量,就等于是某个字段的坐标位置(指针)。