Unsafe类常用方法整理

5 篇文章 0 订阅

说明

  • 为什么要整理Unsafe类的API呢?
    • 因为在阅读JUC的源码的过程中,会发现大量使用了Unsafe类的API,如果不熟悉API的作用,那么阅读过程中多少会有点阻力。

API

  • long objectFieldOffset(Field field)返回指定的变量在所属类中的内存偏移地址,该偏移地址仅仅在该Unsafe函数中访问指定字段时使用。
  • 上面这句话很重要,理解这句话,这个类也就很简单了
static {  
    try {  
        valueOffset = unsafe.objectFieldOffset(AtomicLong.class.getDeclaredField("value"));  
    } catch (Exception ex) {  
        throw new Error(ex);  
    }  
}
  • 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。这是一个有延迟的putLongvolatile方法,并且不保证值修改对其他线程立刻可见。只有在变量使用volatile修饰并且预计会被意外修改时才使用该方法。
  • void park(boolean isAbsolute, long time)方法:阻塞当前线程,其中参数isAbsolute等于false且time等于0表示一直阻塞。
  • 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类注意事项

  1. 加载Unsafe必须是Bootstrap类加载器加载,否者会抛出安全异常,因此调用Unsafe.getUnsafe这个方法是不能用的
  2. 所以,必须通过反射来获取Unsafe对象
public class TestUnSafe {  
  
    static final Unsafe unsafe;  
    static final long stateOffset;  
    private volatile long state = 0;  
  
    static {  
        try { //使用反射获取Unsafe的成员变量  
            Field field = Unsafe.class.getDeclaredField("theUnsafe");  
            // 设置为可存取  
            field.setAccessible(true);  
            // 获取该变量的值   
unsafe = (Unsafe) field.get(null);  
            //获取state在TestUnSafe中的偏移量   
stateOffset = unsafe.objectFieldOffset(TestUnSafe.class.getDeclaredField("state"));  
        } catch (Exception ex) {  
            System.out.println(ex.getLocalizedMessage());  
            throw new Error(ex);  
        }  
    }}

参考:java并发编程之美2.9 Unsafe类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值