Java9 series (7) Variable Handles

  java9

Order

This article mainly studiesJEP 193: Variable Handles

Variable Handles

The API of Variable Handles is mainly used to replace the functions of java.util.concurrent.atomic package and sun.misc.Unsafe class. A variable handle is a variable type reference used to read and write variables in a series of access modes. Supported variables include instance variables, static members, data elements, etc. Variable Handles needs to rely on jvm enhancement and compiler assistance, that is, it needs to rely on java language specification and jvm specification upgrade.

Example

Target class

    public static class Demo {
        public int count = 1;
        protected long sum = 100;
        private String name = "init";
        public int[] arrayData = new int[]{3,5,7};

        @Override
        public String toString() {
            return "Demo{" +
                    "name='" + name + '\'' +
                    ", count=" + count +
                    ", sum=" + sum +
                    ", data=" + Arrays.toString(arrayData) +
                    '}';
        }
    }

Access public members

    @Test
    public void testSetPublicField() throws NoSuchFieldException, IllegalAccessException {
        Demo instance = new Demo();
        VarHandle countHandle = MethodHandles.lookup()
                .in(Demo.class)
                .findVarHandle(Demo.class, "count", int.class);
        countHandle.set(instance,99);
        System.out.println(instance.count);
    }

Output

99

Visit proteced members

    @Test
    public void testSetProtectedField() throws NoSuchFieldException, IllegalAccessException {
        Demo instance = new Demo();
        VarHandle countHandle = MethodHandles.lookup()
                .in(Demo.class)
                .findVarHandle(Demo.class, "sum", long.class);
        countHandle.set(instance,99999);
        System.out.println(instance);
    }

Output

Demo{name='init', count=1, sum=99999, data=[3, 5, 7]}

Access to private members

    @Test
    public void testSetPrivateField() throws NoSuchFieldException, IllegalAccessException {
        Demo instance = new Demo();
        VarHandle countHandle = MethodHandles.privateLookupIn(Demo.class,MethodHandles.lookup())
                .findVarHandle(Demo.class, "name", String.class);
        countHandle.set(instance,"hello world");
        System.out.println(instance);
    }

Output

Demo{name='hello world', count=1, sum=100, data=[3, 5, 7]}

Access array type

    @Test
    public void testSetArray(){
        Demo instance = new Demo();
        VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(int[].class);
        arrayVarHandle.compareAndSet(instance.arrayData,0,3,100);
        arrayVarHandle.compareAndSet(instance.arrayData,1,5,300);
        System.out.println(instance);
    }

Output

Demo{name='init', count=1, sum=100, data=[100, 300, 7]}

access modes

The main access modes are as follows:

read access modes

such as reading a variable with volatile memory ordering effects;
There are mainly the following methods: get, getvolatile, getacquire, getopaque.

  • get

with memory semantics of reading as if the variable was declared non-{@code volatile}. Commonly referred to as plain read access.

  • getVolatile

Variable used to read volatile decoration

  • getAcquire

ensures that subsequent loads and stores are not reordered before this access.

  • getOpaque

accessed in program order, but with no assurance of memory ordering effects with respect to other threads.

write access modes

such as updating a variable with release memory ordering effects;
There are mainly the following methods: set, set volatile, set release, set opaque.

atomic update access modes

such as a compare-and-set on a variable with volatile memory order effects for both read and writing;
There are mainly the following methods: ComparativeSet, WeakComparativeSet, WeakComparativeSet, WeakComparativeSet, WeakComparativeSet, WeakComparativeSet Release, ComparativeExchangeAchuire, compareAndExchange, compareAndExchangeRelease, getAndSet, getAndSetAcquire, getAndSetRelease.

numeric atomic update access modes

such as get-and-add with plain memory order effects for writing and acquire memory order effects for reading.
There are mainly the following methods: GetAnddad, GetAndAddAcquire, GetAndAddresse

bitwise atomic update access modes

such as get-and-bitwise-and with release memory order effects for writing and plain memory order effects for reading.
There are mainly the following methods: GetAndBitwise, GetAndBitwise Eoracquire, GetAndBitwise Eorrelease, GetAndBitwise Eand, GetAndBitwise Eandacquire, GetAndBitwise Eandelease, getAndBitwiseXor, getAndBitwiseXorAcquire, getAndBitwiseXorRelease.

Summary

Java9 abandoned the sun.misc.Unsafe class and introduced VarHandle as a substitute. Regarding access modes, the memory model of JVM is involved. You need to know the memory visibility and instruction reordering before you can use the relevant api.

doc