JDK 9中新增的库,是java.util.concurrent.atomic和sun.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条)