12.Unsafe原子性操作

import sun.misc.Unsafe;

/**
 * JDK8
 * JDK 的此jar 包中的 Unsafe 类提供了硬件级别的原子性操作
 */
public class UnsafeTest {
    //获得Unsafe的一个实例
    static final Unsafe unsafe1 = Unsafe.getUnsafe();
    static final long stateOffset;
    private volatile long state = 0;

    static {
        try {
            //获取 UnsafeTest 类里面的 state 变量, 在 UnsafeTest 对象里面的内存偏移量地址并将其保存到 stateOffset 变量中。
            //getDeclaredFields():获得某个类的所有声明的字段
            stateOffset = unsafe1.objectFieldOffset(UnsafeTest.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            System.out.println(e.getLocalizedMessage());
            throw new Error(e);
        }
    }
    public static void main(String[] args){
        UnsafeTest unsafeTest = new UnsafeTest();
        //如果 test 对象中 内存偏移量为 stateOffset 的 state 变量的值为 0,则更新该值为 1
        boolean b = unsafe1.compareAndSwapInt(unsafeTest, stateOffset, 0, 1);
        System.out.println(b);
        //Exception in thread "main" java.lang.ExceptionInInitializerError
        //Caused by: java.lang.SecurityException: Unsafe
        //  at sun.misc.Unsafe.getUnsafe(Unsafe.java:90)
        //  at com.fly.two.UnsafeTest.<clinit>(UnsafeTest.java:10)
        //正常无法实例化 Unsafe 类
    }
}
import sun.misc.Unsafe;

import java.lang.reflect.Field;

import static com.fly.two.UnsafeTest.unsafe1;

/**
 * JDK8
 * 通过反射来获取 Unsafe 实例方法。
 */
public class UnsafeTest2 {
    //获得Unsafe的一个实例
    static final Unsafe unsafe;
    static final long stateOffset;
    private volatile long state = 0;

    static {
        try {
            //使用反射获取Unsafe的成员变量theUnsafe
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            //设置为可存取
            field.setAccessible(true);
            //获取该变量的值
            unsafe = (Unsafe) field.get(null);
            //获取 UnsafeTest 类里面的 state 变量, 在 UnsafeTest 对象里面的内存偏移量地址并将其保存到 stateOffset 变量中。
            //getDeclaredFields():获得某个类的所有声明的字段
            stateOffset = unsafe.objectFieldOffset(UnsafeTest2.class.getDeclaredField("state"));
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            throw new Error(e);
        }
    }
    public static void main(String[] args){
        UnsafeTest2 unsafeTest = new UnsafeTest2();
        //如果 test 对象中 内存偏移量为 stateOffset 的 state 变量的值为 0,则更新该值为 1
        boolean b = unsafe.compareAndSwapInt(unsafeTest, stateOffset, 0, 1);
        System.out.println(b);//true
    }
}
上一篇:java – 为什么sun.misc.Unsafe存在,它如何在现实世界中使用?


下一篇:《Linux内核分析》第六周 读书笔记