1.简介
Varhandle
是对变量或参数定义的变量系列的动态强类型引用,包括静态字段,非静态字段,数组元素或堆外数据结构的组件。 在各种访问模式下都支持访问这些变量,包括简单的读/写访问,volatile 的读/写访问以及 CAS (compare-and-set)访问。Variable
就是对这些变量进行绑定,通过 Varhandle
直接对这些变量进行操作。 之前介绍的 Unsafe
所操作的并不属于Java标准,会容易带来一些安全性的问题。官方推荐使用 java.lang.invoke.Varhandle
来替代 Unsafe
大部分功能,Varhandle
更加安全,并且,在并发方面也提高了不少性能。
2.功能
VarHandle来使用plain、opaque、release/acquire和volatile四种共享内存的访问模式,根据这四种共享内存的访问模式又分为写入访问模式、读取访问模式、原子更新访问模式、数值更新访问模式、按位原子更新访问模式。
3.实例
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Arrays;
public class VarHandleDemo {
public int publicValue = 1;
protected int protectedValue = 2;
private int privateValue = 3;
public int[] array = new int[]{1, 2, 3};
@Override
public String toString() {
return "VarHandleDemo{" +
" publicValue=" + publicValue +
", protectedValue=" + protectedValue +
", privateValue=" + privateValue +
", array=" + Arrays.toString(array) +
'}';
}
public static void main(String[] args) throws Exception {
VarHandleDemo demo=new VarHandleDemo();
//访问 private,public,protected 均可
/**
* VarHandle varHandle = MethodHandles.privateLookupIn(VarHandleDemo.class, MethodHandles.lookup())
.findVarHandle(VarHandleDemo.class, "privateValue", int.class);
*/
VarHandle varHandle =MethodHandles.lookup()
.in(VarHandleDemo.class)
.findVarHandle(VarHandleDemo.class, "publicValue", int.class);
varHandle.set(demo, 13);
//数组
VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(int[].class);
//数字对象,下标,预期值,新值
arrayVarHandle.compareAndSet(demo.array, 0, 1, 11);
arrayVarHandle.compareAndSet(demo.array, 1, 2, 22);
arrayVarHandle.compareAndSet(demo.array, 2, 3, 33);
System.out.println(demo);
}
}