VarHandle เป็น reference ไปยัง variable ให้ access ตัวแปรภายใต้ access modes ต่างๆ (plain read/write, volatile read/write, compare-and-swap) คล้ายกับ java.util.concurrent.atomic และ sun.misc.Unsafe ตัวแปรอาจเป็น array elements, instance fields หรือ static fields
ตัวอย่าง: Static VarHandle
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
public class StaticVarHandleTest {
static int field;
static int[] array = new int[20];
static final VarHandle FIELD, ARRAY;
static {
try {
FIELD = MethodHandles.lookup()
.in(StaticVarHandleTest.class)
.findStaticVarHandle(StaticVarHandleTest.class, "field", Integer.TYPE);
ARRAY = MethodHandles.arrayElementVarHandle(int[].class);
} catch(Exception e) {
throw new InternalError(e);
}
}
public static void main(String args[]) throws Exception {
int i = (int) FIELD.getVolatile();
System.out.println(i); // 0
FIELD.getAndAdd(5);
System.out.println(field); // 5
System.out.println(ARRAY.getAndAdd(array, 5, 5)); // 0
System.out.println(ARRAY.getAndAdd(array, 5, 5)); // 5
}
}
ผลลัพธ์
0
5
0
5
คำอธิบายโค้ด
- FIELD - VarHandle สำหรับ static field
field ใช้ findStaticVarHandle
- ARRAY - VarHandle สำหรับ array elements ใช้
arrayElementVarHandle
- MethodHandles.lookup().in(Class) - Lookup ใน context ของคลาสนั้น (เข้าถึง private ได้)
- getVolatile() - Volatile read
- getAndAdd() - Atomic get-and-add (compare-and-swap loop)
VarHandle Access Modes
| Mode |
Methods |
คำอธิบาย |
| Plain |
get(), set() |
Normal read/write, no ordering guarantees |
| Volatile |
getVolatile(), setVolatile() |
Volatile semantics, happens-before |
| Acquire/Release |
getAcquire(), setRelease() |
Weaker than volatile, for locking |
| Opaque |
getOpaque(), setOpaque() |
Coherent but no ordering |
| Compare-and-Swap |
compareAndSet(), weakCompareAndSet() |
Atomic conditional update |
| Atomic Numeric |
getAndAdd(), getAndSet(), getAndIncrement() |
Atomic read-modify-write |
| Bitwise |
getAndBitwiseOr(), getAndBitwiseAnd(), getAndBitwiseXor() |
Atomic bitwise operations |
การสร้าง VarHandle ประเภทต่างๆ
// Static field
VarHandle staticHandle = MethodHandles.lookup()
.in(MyClass.class)
.findStaticVarHandle(MyClass.class, "fieldName", FieldType.class);
// Instance field
VarHandle instanceHandle = MethodHandles.lookup()
.in(MyClass.class)
.findVarHandle(MyClass.class, "fieldName", FieldType.class);
// Array elements
VarHandle arrayHandle = MethodHandles.arrayElementVarHandle(ElementType[].class);
// ByteBuffer (direct memory)
VarHandle bufferHandle = MethodHandles.byteBufferViewVarHandle(
ByteOrder.nativeOrder(), FieldType.class);
VarHandle vs Atomic Classes vs Unsafe
| Feature |
VarHandle |
Atomic* Classes |
Unsafe |
| Standard API |
Yes (Java 9+) |
Yes (Java 5+) |
No (internal) |
| Memory ordering modes |
All (7 modes) |
Volatile only |
All |
| Works on fields |
Yes (static/instance) |
No (wrapper objects) |
Yes |
| Works on arrays |
Yes |
AtomicIntegerArray etc. |
Yes |
| Method handles integration |
Yes |
No |
No |
ข้อดีของ VarHandle
- Standard API แทน Unsafe
- รองรับ memory ordering modes ครบ
- ทำงานกับ fields และ arrays โดยตรง
- Integrate กับ MethodHandles ได้
- Performance ใกล้เคียง Unsafe