## 序
本文主要研究下[JEP 193: Variable Handles](http://openjdk.java.net/jeps/193)
## Variable Handles
Variable Handles的API主要是用来取代java.util.concurrent.atomic包以及sun.misc.Unsafe类的功能。一个variable handle是一个variable的类型引用,用来在一系列访问模式下来读写variable。支持的variable包括实例变量,静态成员,数据元素等。Variable Handles需要依赖jvm的增强及编译器的协助,即需要依赖java语言规范及jvm规范的升级。
## 实例
### 目标类
```
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);
}
```
输出
```
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);
}
```
输出
```
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);
}
```
输出
```
Demo{name='init', count=1, sum=100, data=[100, 300, 7]}
```
## access modes
主要的访问模式有如下几种:
### 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。
## doc
- [JDK 9 features](http://openjdk.java.net/projects/jdk9/)
- [JEP 193: Variable Handles](http://openjdk.java.net/jeps/193)
- [VarHandle](https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html)
- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles)
- [Java 9 series: Variable Handles](https://www.voxxed.com/2016/11/java-9-series-variable-handles/)
- [Variable Handle In Java 9](https://www.javagists.com/variable-handle-java9)
- [Correct way to use VarHandle in Java 9?](https://stackoverflow.com/questions/43558270/correct-way-to-use-varhandle-in-java-9)
- [Java 9 Variable Handles](http://eppleton.de/news/java-9-variable-handles_2017-06-01.html)