参考:https://www.cnblogs.com/duanxz/p/6097779.html
package com.test; import sun.misc.Unsafe; import java.lang.reflect.Field; public class CASLearn { private static final Unsafe unsafe; private static final long nameOffset; private static final long valueOffset; private static final long intffset; //为了保证多线程间的可见性,所以声明为volatile 但是这个例子是单线程的 private volatile String name; private volatile long value; private volatile int age; static { try { //unsafe无法直接调用Unsafe.getUnsafe()去获取实例,这个方法只对可信任的类才能获取。 ///通过反射获取unsafe Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference f.setAccessible(true); unsafe = (Unsafe) f.get(null); //静态代码块初始化每个属性的偏移量 //CASLearn.class.getDeclaredField("value") 能获取到value属性的原因是java的类加载机制: //参考:https://blog.csdn.net/m0_38075425/article/details/81627349 // 1.加载:读取class二进制流,将类的数据结构存储值方法区,然后新建一个class对象,用来指向该类的数据结构 // 2.验证:确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。其主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证 // 3.准备:为类的静态变量分配内存,并设置默认初始值。(int初始值为0) // 4.解析:将类的二进制数据中的符号引用替换成直接引用 // 5.初始化:从上到下,给类的静态变量赋值,包括执行static静态代码块 valueOffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("value")); nameOffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("name")); intffset = unsafe.objectFieldOffset(CASLearn.class.getDeclaredField("age")); } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } } private CASLearn(String name, long value, int age) { this.name = name; this.value = value; this.age = age; } @Override public String toString() { return "name:" + name + " age" + age + " value" + value; } public static void main(String[] args) { CASLearn cas = new CASLearn("dh", 100L, 18); //原子操作:修改age 18->19 unsafe.compareAndSwapInt(cas, intffset, 18, 19); //原子操作,value的值为100L,不是200L,所以不修改 unsafe.compareAndSwapLong(cas, valueOffset, 200L, 999L); //原子操作,修改"dh"->"hiahiahia" unsafe.compareAndSwapObject(cas, nameOffset, "dh", "hiahiahia"); //结果为:name:hiahiahia age19 value100 System.out.println(cas); }