前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java9系列(七)Variable Handles

java9系列(七)Variable Handles

作者头像
code4it
发布2018-09-17 15:57:50
9960
发布2018-09-17 15:57:50
举报
文章被收录于专栏:码匠的流水账码匠的流水账

## 序

本文主要研究下[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)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档