Unsafe类

Posted wqff-biubiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unsafe类相关的知识,希望对你有一定的参考价值。

一、Unsafe类仅能被BootstrapClassLoader加载的类实例化,用户建的类默认都是ApplicationClassLoader加载的,实例化Unsafe时会报错。可以用反射实例化(方式一)。补充:加启动参数指定当前类由BootstrapClassLoader加载(方式二)

    private Unsafe() {//构造方法私有化 同单例模式 防止new
    }

    @CallerSensitive
    public static Unsafe getUnsafe() {
        Class var0 = Reflection.getCallerClass();
        if (!VM.isSystemDomainLoader(var0.getClassLoader())) {//判断是否BootstrapClassLoader加载的类执行实例化的
            throw new SecurityException("Unsafe");
        } else {
            return theUnsafe;
        }
    }

二、反射实现实例化

public class UnsafeTest2 {
    static final Unsafe unsafe;

    static final long stateOffset;

    private volatile long state = 0;

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe)field.get(null);//反射得到Unsafe实例
            stateOffset = unsafe.objectFieldOffset(UnsafeTest.class.getDeclaredField("state"));
        }catch (Exception e){
            System.out.println(e.getLocalizedMessage());
            throw new Error(e);
        }
    }

    public static void main(String[] args){
        UnsafeTest2 test = new UnsafeTest2();
        Boolean sucess = unsafe.compareAndSwapInt(test,stateOffset,0,1);
        System.out.println(sucess);
    }
}

三、重要方法

long objectFieldOffset(Field field):返回指定的变量在所属类中的内存偏移地址

int arrayBaseOffset(Class arrayClass):获取数组中第一个元素的地址。

int arrayIndexScale(Class arrayClass):获取数组中第一个元素占用的字节。

boolean compareAndSwapLong(Object obj,long offset,long expect,long update):比较对象obj中偏移量为offset的变量的值是否与expect相等,相等则使用update更新,然后返回true,否则返回false。

public native long getLongvolatile(Object obj,long offset):获取obj对象中偏移量为offset的变量对应的volatile语义的值。

void putLongvolatile(Object obj,long offset,long value):设置obj对象中offset偏移的类型为long的field的值的value,支持volatile语义(可见性,有序性)

void putOrderedLong(Object obj,long offset,long value):设置obj对象中offset偏移地址对应的long型field的值为value,无volatile语义(可见性,有序性)

void park(boolean isAbsolute,long time):阻塞当前线程,其中参数isAbsolute等于false且time等于0时表示一直阻塞

void unpark(Object thread):唤醒调用park后阻塞的线程。

long getAndSetLong(Object obj,long offset,long update):获取对象obj中偏移量为offset的变量volatile语义的当前值,并设置变量volatile语义的值为update。

long getAndAddLong(Object obj,long offset,long addValue):获取对象obj中偏移量为offset的变量volatile语义的当前值,并设置变量的值为原始值+addValue。

以上是关于Unsafe类的主要内容,如果未能解决你的问题,请参考以下文章

java的sun.misc.Unsafe类

Unsafe与CAS

java 非阻塞算法实现基础:unsafe类介绍

Java并发:CAS Unsafe Atomic

Unsafe

Java中的Unsafe类