Unsafe获取

介绍
  • public native long objectFieldOffset方法:返回指定 的变量在所属类 中的内存偏移地址,
    该偏移地址仅仅在该 Unsafe 函数中访 问指定宇段时使用

  • public native int arrayBaseOffset(Class<?> var1) 获取数组中第一个元素的地址

  • public native int arrayIndexScale(Class<?> var1) 获取数组中一个元素 占用的字节

  • public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6)
    比较对象 obj 中偏移量为 offset 的变量 的值是否与 expect 相等 , 相等则使用 update
    值更新 , 然后返回 tru巳,否则返回 false

  • public native long getLongVolatile(Object var1, long var2) 获取对象 obj 中偏移量为 offset 的变量对应 volatile i吾义的值

  • public native void putLongVolatile(Object var1, long var2, long var4) 设置 obj 对 象 中 offset偏移 的类型为 long 的 field 的值为 value,支持 volatile 语义

  • public native void putOrderedLong(Object var1, long var2, long var4) 置 obj 对象 中 offset偏移地址对应的 long 型 field 的值为 value 。 这是一个有延迟的 putLongvolatile 方法 ,并且不保证值修改对其他线程立刻可见 。 只有在变量使用 volatile 修饰并且预计会被意外修改时才使用 该方法

  • public native void park(boolean var1, long var2) 阻塞 当 前线程 , 其 中 参数 isAbsolute等于 false 且 time 等于 0 表示一直阻塞 。 time 大于 0 表示等待指定 的 time 后阻塞线
    程会被唤醒 , 这个 time 是个相对值 , 是个增量值 , 也就是相对 当前时间 累加 time后当前线程就会被唤醒 。 如果 isAbsolute 等于 true , 并且 time 大于 0,则表示 阻塞
    的 线程到 指定的 时 间点后会被唤醒,这里 time 是个绝对时间, 是将某个时间 点换算为 ms 后 的值 。 另 外,当其他线程调用 了 当 前阻塞线程 的 intemrrupt 方法而中断 了
    当前线程 时-, 当 前线程也会返 回, 而 当其他线程调用 了 unPark 方法并且把 当 前线程作为参数时当前线程也会返回

  • public native void unpark(Object var1) 唤醒调用 park 后阻塞 的线程。

  • public final long getAndSetLong(Object var1, long var2, long var4) 获取对象 obj 中偏移
    量为 offset 的变量 volatile i吾义的当前值 , 并设置变量 volatile i吾义的值为 update

public final long getAndSetLong(Object var1, long var2, long var4) {
        long var6;
        do {
        //getLongvolatile 获取当前变量的值 
            var6 = this.getLongVolatile(var1, var2);
            //使用CAS比较 CAS 原子操作设置新值 。这里使用 while 循环是考虑到,在多个线程 同时调用的情 况下 CAS 失败时需要重试		
        } while(!this.compareAndSwapLong(var1, var2, var6, var4));

        return var6;
    }
  • long getAndAddLong(Object var1, long var2, long var4) 获取对象 。同 中偏移量为 offset 的变量 volatile i吾义的当前值 , 并设置变量值为原始值+addValue
 public final long getAndAddLong(Object var1, long var2, long var4) {
        long var6;
        do {
        //getLongvolatile 获取当前变量的值
            var6 = this.getLongVolatile(var1, var2);
            //进行 CAS 操作时使用了原始值+传递的增量参数 addValue 的值
        } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

        return var6;
    }
简单使用
package com.ghgcn.threadstudy.lesson01;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author 刘楠
 * @since 2019/7/1
 */
public class TestUnSafe1 {

    private   static    Unsafe unsafe;
    private  static    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);
            //获取偏移量
            stateOffset=unsafe.objectFieldOffset(TestUnSafe1.class.getDeclaredField("state"));




        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
            System.err.println(e.getLocalizedMessage());
        }
    }
    public static void main(String[] args) {

        TestUnSafe1 testUnSafe1 = new TestUnSafe1();

        boolean success = unsafe.compareAndSwapLong(testUnSafe1, stateOffset, 0, 2);
        System.out.println("success "+success);

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值