VarHandle 把 plain、opaque、acquire/release、volatile 四档读写与 CAS 都放进一个对象。不同变量到底支持哪几种?类型写错抛什么?字节码是什么样?这篇逐项量。
AccessMode 总数:31
字段 i (int) 31/31
字段 l (long) 31/31
字段 b (boolean) 28/31 不支持:[getAndAdd, getAndAddAcquire, getAndAddRelease]
字段 s (String) 19/31 不支持:[getAndAdd, getAndAddAcquire, getAndAddRelease, getAndBitwiseOr, getAndBitwiseOrRelease, getAndBitwiseOrAcquire, getAndBitwiseAnd, getAndBitwiseAndRelease, getAndBitwiseAndAcquire, getAndBitwiseXor, getAndBitwiseXorRelease, getAndB
字段 vi (int,volatile) 31/31
字段 f (int,final) 4/31 不支持:[set, setVolatile, setRelease, setOpaque, compareAndSet, compareAndExchange, compareAndExchangeAcquire, compareAndExchangeRelease, weakCompareAndSetPlain, weakCompareAndSet, weakCompareAndSetAcquire, weakCompareAndSetRelease]…共27
字段 d (double) 22/31 不支持:[getAndBitwiseOr, getAndBitwiseOrRelease, getAndBitwiseOrAcquire, getAndBitwiseAnd, getAndBitwiseAndRelease, getAndBitwiseAndAcquire, getAndBitwiseXor, getAndBitwiseXorRelease, getAndBitwiseXorAcquire]
int[] 元素 31/31
String[] 元素 19/31 不支持:[getAndAdd, getAndAddAcquire, getAndAddRelease, getAndBitwiseOr, getAndBitwiseOrRelease, getAndBitwiseOrAcquire, getAndBitwiseAnd, getAndBitwiseAndRelease, getAndBitwiseAndAcquire, getAndBitwiseXor, getAndBitwiseXorRelease, getAndBit
byte[] 视图 int 31/31
byte[] 视图 long 31/31
ByteBuffer 视图 int 31/31
坐标类型 / 值类型(字段 i):[class Main] / int
accessModeType(COMPARE_AND_SET)= (Main,int,int)boolean
accessModeType(GET_AND_ADD) = (Main,int)int I.set(m, 5) → 成功
I.set(m, 5L)(long 传给 int) → WrongMethodTypeException: cannot convert MethodHandle(VarHandle,Main,int)void to (VarHandle,Main,long)void
I.set(m, (short) 5)(short 可以宽化到 int) → 成功
I.set(m, "x") → WrongMethodTypeException: cannot convert MethodHandle(VarHandle,Main,int)void to (VarHandle,Main,String)void
I.set(m)(少一个参数) → WrongMethodTypeException: cannot convert MethodHandle(VarHandle,Main,int)void to (VarHandle,Main)void
I.set(null, 1)(null 对象) → NullPointerException: null
int x = (int) I.get(m) → 成功
long x = (long) I.get(m)(int 窄到 long 宽化) → 成功
Object x = I.get(m)(没有强转,返回 Object) → 成功
F.set(m, 2)(final 字段 set) → UnsupportedOperationException: set
F.compareAndSet(m, 1, 2) → UnsupportedOperationException: compareAndSet
F.get(m) → 成功
LL.compareAndSet(m, 0, 1)(int 字面量对 long 字段) → 成功
LL.compareAndSet(m, 0L, 1L) → 成功
I.getAndAdd(m, 3) 的返回类型 int → 成功
S.getAndAdd(m, "x")(引用类型没有数值原子操作) → UnsupportedOperationException: getAndAdd
I.compareAndSet(m, 5, 6) 返回 boolean → 成功
I.get(m) 与 I.getVolatile / getOpaque / getAcquire → 成功
S.set(m, new StringBuilder())(类型不兼容的引用) → ClassCastException: Cannot cast java.lang.StringBuilder to java.lang.String
S.set(m, (CharSequence) "x")(静态类型是 CharSequence) → 成功
S.set(m, (Object) "x")(静态类型是 Object) → 成功 static final java.lang.invoke.VarHandle I;
8: getstatic #10 // Field I:Ljava/lang/invoke/VarHandle;
13: invokevirtual #14 // Method java/lang/invoke/VarHandle.setRelease:(LMain;I)V
16: getstatic #10 // Field I:Ljava/lang/invoke/VarHandle;
20: invokevirtual #20 // Method java/lang/invoke/VarHandle.getAcquire:(LMain;)I
24: getstatic #10 // Field I:Ljava/lang/invoke/VarHandle;
31: invokevirtual #24 // Method java/lang/invoke/VarHandle.compareAndSet:(LMain;II)Z
10: invokevirtual #60 // Method java/lang/invoke/MethodHandles$Lookup.findVarHandle:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/i
13: putstatic #10 // Field I:Ljava/lang/invoke/VarHandle;
运行: 5 true 6 第 1 轮:纯普通读写违例 0;setRelease/getAcquire 违例 0;storeStoreFence/loadLoadFence 违例 0;volatile 违例 0
第 2 轮:纯普通读写违例 0;setRelease/getAcquire 违例 0;storeStoreFence/loadLoadFence 违例 0;volatile 违例 0
第 3 轮:纯普通读写违例 0;setRelease/getAcquire 违例 0;storeStoreFence/loadLoadFence 违例 0;volatile 违例 0