java 并发包-Unsafe

Unsafe 不安全类,在并发包中使用的非常频繁,那么它究竟有什么作用呢?
Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。
先来看下它是怎么使用的,下面代码摘自AQS
通过下面的代码,看起来操作不难

//初始化 直接通过静态方式获取
 private static final Unsafe unsafe = Unsafe.getUnsafe();
 //各种偏移量
    private static final long stateOffset;
...

    static {
        try {
        //初始化偏移量  通过使用objectFieldOffset方法
        //long sun.misc.Unsafe.objectFieldOffset(Field arg0) 参数Field 获取对应字段的偏移量
            stateOffset = unsafe.objectFieldOffset
                (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
            headOffset = unsafe.objectFieldOffset
....

        } catch (Exception ex) { throw new Error(ex); }
    }

    //boolean sun.misc.Unsafe.compareAndSwapObject(Object arg0, long arg1, Object arg2, Object arg3)
    // 1 需要操作的类
    // 2 偏移量
    // 3 原始值
    // 4 替换值
    private final boolean compareAndSetHead(Node update) {
        return unsafe.compareAndSwapObject(this, headOffset, null, update);
    }
 ...

看过怎么使用 再来看下源码吧
1 Unsafe用的是单例模式

public class Unsafe {  
    private static Unsafe unsafe = new Unsafe();  
    private Unsafe() {  
    }  

   //通过安全器安全的获取unsafe 
    public static Unsafe getUnsafe() {  
        SecurityManager sm = System.getSecurityManager();  
        if (sm != null)  
            sm.checkPropertiesAccess();  
        return unsafe;  
    }  

  //返回指定静态field的内存地址偏移量,在这个类的其他方法中这个值只是被用作一个访问 
    public native long objectFieldOffset(Field field);  


     //在obj的offset位置比较object field和期望的值,如果相同则更新。这个方法 的操作应该是原子的,因此提供了一种不可中断的方式更新object field。 
    public native boolean compareAndSwapObject(Object obj, long offset,  
                                               Object expect, Object update);  





    //设置obj对象中offset偏移地址对应的object型field的值为指定值。这是一个有序或者  有延迟的方法,并且不保证值的改变被其他线程立 即看到。只有在field被修饰并且期望被意外修改的时候 
    public native void putOrderedObject(Object obj, long offset, Object value);  

     // 设置obj对象中offset偏移地址对应的object型field的值为指定值。支持volatile store语义 

    public native void putObjectVolatile(Object obj, long offset, Object value);  

     // 设置obj对象中offset偏移地址对应的object型field的值为指定值。 
    public native void putObject(Object obj, long offset, Object value);  
    //获取给定数组中第一个元素的偏移地址。 
    public native int arrayBaseOffset(Class arrayClass);  

//获取用户给定数组寻址的换算因子.一个合适的换算因子不能返回的时候(例如:基本类型), 返回0.这个返回值能够与一起使用去存取这个数组class中的元素 
    public native int arrayIndexScale(Class arrayClass);  
    //释放线程
    public native void unpark(Thread thread); 
    // 阻塞一个线程直到出现、线程 被中断或者timeout时间到期。 
    public native void park(boolean isAbsolute, long time); 

常用的方法一般是park、unpark、objectFieldOffset及compareAndSwapObject
省略了很多方法,不过基本差不多,这里都是调用native本地方法了。
总之呢,我们还是不要直接使用,差不多能理解就行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值