java9系列(七)Variable Handles

本文主要研究下JEP 193: Variable Handleshtml

Variable Handles

Variable Handles的API主要是用來取代java.util.concurrent.atomic包以及sun.misc.Unsafe類的功能。一個variable handle是一個variable的類型引用,用來在一系列訪問模式下來讀寫variable。支持的variable包括實例變量,靜態成員,數據元素等。Variable Handles須要依賴jvm的加強及編譯器的協助,即須要依賴java語言規範及jvm規範的升級。java

實例

目標類

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) +
                    '}';
        }
    }

訪問public成員

@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);
    }

輸出api

99

訪問proteced成員

@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);
    }

輸出數組

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

訪問private成員

@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);
    }

輸出oracle

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

訪問數組類型

@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);
    }

輸出jvm

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

access modes

主要的訪問模式有以下幾種:ide

read access modes

such as reading a variable with volatile memory ordering effects;
主要有以下幾個方法: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
用於讀取volatile修飾的變量
  • 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;
主要有以下幾個方法:set, setVolatile, setRelease, setOpaque.

atomic update access modes

such as a compare-and-set on a variable with volatile memory order effects for both read and writing;
主要有以下幾個方法:compareAndSet, weakCompareAndSetPlain, weakCompareAndSet, weakCompareAndSetAcquire, weakCompareAndSetRelease, compareAndExchangeAcquire, 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.
主要有以下幾個方法:getAndAdd, getAndAddAcquire, getAndAddRelease

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.
主要有以下幾個方法:getAndBitwiseOr, getAndBitwiseOrAcquire, getAndBitwiseOrRelease, getAndBitwiseAnd, getAndBitwiseAndAcquire, getAndBitwiseAndRelease, getAndBitwiseXor, getAndBitwiseXorAcquire, getAndBitwiseXorRelease.

小結

java9廢棄了sun.misc.Unsafe類,引入了VarHandle做爲替代。關於access modes部分涉及了JVM的內存模型,須要瞭解內存可見性、指令重排序等,才能使用好相關api。ui

doc

相關文章
相關標籤/搜索