1.简介

   Varhandle是对变量或参数定义的变量系列的动态强类型引用,包括静态字段,非静态字段,数组元素或堆外数据结构的组件。 在各种访问模式下都支持访问这些变量,包括简单的读/写访问,volatile 的读/写访问以及 CAS (compare-and-set)访问。Variable 就是对这些变量进行绑定,通过 Varhandle 直接对这些变量进行操作。 之前介绍的 Unsafe 所操作的并不属于Java标准,会容易带来一些安全性的问题。官方推荐使用 java.lang.invoke.Varhandle 来替代 Unsafe 大部分功能,Varhandle  更加安全,并且,在并发方面也提高了不少性能。

2.功能

          VarHandle来使用plain、opaque、release/acquire和volatile四种共享内存的访问模式,根据这四种共享内存的访问模式又分为写入访问模式、读取访问模式、原子更新访问模式、数值更新访问模式、按位原子更新访问模式。

VarHandle-LMLPHP

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);
    }
}
04-16 17:10