变量句柄
变量句柄(variable handle)是一种对变量、静态域或数组元素的动态型引用,使你可以多种不同的模式访问该变量。
例如,可以在并发应用程序中对变量进行访问保护,实现对该变量的原子访问。
在此之前,你只能通过原子变量获得这样的行为,但是现在可以使用变量句柄获得同样的功能,而不需要采用任何同步机制。
这是 Java 9 中引入的一种新特性,由 VarHandle 类提供。
访问方法
变量句柄有如下几种访问方法。
- 读取访问模式:
根据不同方法,该模式允许按照不同的内存排序规则读取变量的值。
可以使用 get() 、 getVolatile() 、 getAcquire() 和 getOpaque() 方法读取变量的值。- get()方法将变量视为非易失性变量读取。
- getVolatile()方法将变量作为易失性变量来读取。
- getAcquire()方法确保对该变量的其他访问在该语句之前不会因为优化方面的原因而重新排序。
- getOpaque()方法与getAcquire()类似,但是它仅对当前线程有影响。
- 写入访问模式:
根据方法不同,该模式允许你按照不同的内存排序规则写入变量的值。
可以使用 set() 、 setVolatile() 、 setRelease() 和 setOpaque() 方法。
它们与前面读取访问模式中的方法相对应,只不过是针对写入访问的。 - 原子更新访问模式:
这种模式获得与原子变量类似的功能和操作,例如比较变量的值。- compareAndSet() :
如果作为参数传递的预期值和变量的当前值相等,那么改变变量的值,就像变量是被声明为易失性变量一样。 - weakCompareAndSet() 和 weakCompareAndSetPlain() :
如果作为参数传递的预期值与变量的当前值相等,那么自动将变量的当前值替换为新值。
第一种法将变量视为一个易失性变量,而第二种法将变量视为一个非易失性变量。
- compareAndSet() :
- 数值型原子更新访问模式:
这种模式以原子方式修改数值。
你可以使用下面的方法。- getAndAdd() :
增加变量的值并且返回之前的值,因为该变量被原子自动声明为一个易失性变量。
- getAndAdd() :
- 位原子更新访问模式:
这种模式以原子方式按位修改值。你可以使用 getAndBitwiseOr()或者 getAndBitwiseAnd() 方法。
样例代码
J15VariableHandles
执行本例时,将看到如何使 safeValue 属性的值总如预期一样为 0,但是 unsafeValue 属性的值每次执行时都不同,因为会遇到数据竞争条件。