VarHandle,可变句柄解析

JDK 9中新增的库,是java.util.concurrent.atomicsun.misc.Unsafe操作的等价替代。VarHandle是通用的对象的域的引用句柄,提供原子的操作方法。
直接看用法即可。

// 对象域
private volatile int state;
private volatile Thread runner;
private volatile WaitNode waiters;
// 通用句柄
private static final VarHandle STATE;
private static final VarHandle RUNNER;
private static final VarHandle WAITERS;
// 在类中查找域的位置,并初始化
static {
    try {
        MethodHandles.Lookup l = MethodHandles.lookup();
        STATE = l.findVarHandle(FutureTask.class, "state", int.class);
        RUNNER = l.findVarHandle(FutureTask.class, "runner", Thread.class);
        WAITERS = l.findVarHandle(FutureTask.class, "waiters", WaitNode.class);
    } catch (ReflectiveOperationException e) {
        throw new ExceptionInInitializerError(e);
    }
}

它提供get, set, compareAndSet之类的原子操作。典型的用法如下,它首先传入实例引用(this),取得this对象中的state字段,对比是否等于NEW,如果是则赋值为COMPLETING,并且返回true,否则返回false。

if (STATE.compareAndSet(this, NEW, COMPLETING)) {

}

它的原理,我猜测和UNSAFE的版本非常像。

    // 句柄,其实也是相对于类的偏移量
    private static final long stateOffset;
    private static final long runnerOffset;
    private static final long waitersOffset;
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> k = FutureTask.class;
            stateOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("state"));
            runnerOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("runner"));
            waitersOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("waiters"));
        } catch (Exception e) {
            throw new Error(e);
        }
    }

来看UNSAFE版本如何完成compaeAndSet。它同样传入对象实例,字段偏移量,从而对某个字段进行原子的对比更新。

if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING))

参考

https://www.baeldung.com/java-variable-handles
https://segmentfault.com/a/1190000013544841
https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html#compareAndSet-java.lang.Object…-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值