Varhandle 为java9新加功能,用来代替 Unsafe 供开发者使用。直接上代码:
变量定义
private int plainStr; //普通变量
private static int staticStr; //静态变量
private int reflectStr; //通过反射生成句柄的变量
private int[] arrayStr = new int[]{100, 200, 300}; //数组变量
VarHandle 获取
private static final VarHandle plainVar; //普通变量句柄
private static final VarHandle staticVar; //静态变量句柄
private static final VarHandle reflectVar; //反射字段句柄
private static final VarHandle arrayVar; //数组句柄
static
{
try
{
MethodHandles.Lookup lookup = MethodHandles.lookup();
plainVar = lookup.findVarHandle(VarHandleTest.class, "plainStr", int.class);
staticVar = lookup.findStaticVarHandle(VarHandleTest.class, "staticStr", int.class);
reflectVar = lookup.unreflectVarHandle(VarHandleTest.class.getDeclaredField("reflectStr"));
arrayVar = MethodHandles.arrayElementVarHandle(int[].class);
} catch (ReflectiveOperationException e)
{
throw new ExceptionInInitializerError(e);
}
}
VarHandle 使用
public void testVarHandle()
{
VarHandleTest test = new VarHandleTest();
int plainAdd01 = (int)plainVar.getAndAdd(test, 1); //CAS
int plainAdd02 = (int)plainVar.get(test); //non-volatile
int staticAdd01 = (int)staticVar.getAndAdd(10); //CAS
int staticAdd02 = (int)staticVar.get(); //non-volatile
reflectVar.compareAndSet(test, 0, 5); //CAS
int reflectSet = (int)reflectVar.get(test); //non-volatile
arrayVar.compareAndSet(test.arrayStr,0,100,10000); //CAS
arrayVar.compareAndSet(test.arrayStr,1,200,20000); //CAS
System.out.println("plainVar01 : " + plainAdd01 +", plainVar02 : " + plainAdd02);
System.out.println("staticVar01 : " + staticAdd01 +", staticVar02 : " + staticAdd02);
System.out.println("reflectVar : " + reflectSet);
System.out.println("arrayVar : " + Arrays.toString(test.arrayStr));
}
程序运行输出
plainVar01 : 0, plainVar02 : 1
staticVar01 : 0, staticVar02 : 10
reflectVar : 5
arrayVar : [10000, 20000, 300]