关于 JDK 9 的 VarHandle 访问模式
Plain: read ({@code get}) and write ({@code set}) accesses are guaranteed to be bitwise atomic only for references and for primitive values of at most 32 bits, and impose no observable ordering constraints with respect to threads other than the executing thread.
Opaque:operations are bitwise atomic and coherently ordered with respect to accesses to the same variable.
Acquire: reads and their subsequent accesses are ordered after matching
Release: mode writes and their previous accesses.
**Volatile: **operations are totally ordered with respect to each other.
/**
* Sets the value of a variable to the {@code newValue}, in program order, but with no assurance of memory ordering effects with respect to other threads.
* Returns the value of a variable, accessed in program order, but with no assurance of memory ordering effects with respect to other threads.
**/
void setOpaque(Object... args);
Object getOpaque(Object... args);
/**
* Returns the value of a variable, and ensures that subsequent loads and stores are not reordered before this access.
* Sets the value of a variable to the {@code newValue}, and ensures that prior loads and stores are not reordered after this access.
**/
Object getAcquire(Object... args);
void setRelease(Object... args);
/**
* Returns the value of a variable, with memory semantics of reading as if the variable was declared {@code volatile}.
* Sets the value of a variable to the {@code newValue}, with memory semantics of setting as if the variable was declared {@code volatile}.
**/
Object getVolatile(Object... args);
void setVolatile(Object... args);
====================== 1 =================================
Using JDK 9 Memory Order Modes,讲了怎样通过 VarHandle 来使用 plain、opaque、release/acquire 和 volatile 四种共享内存的访问模式,并剖析了底层的原理。
https://17bdw.com/common/00_Programer_learn_Strategy/
http://gee.cs.oswego.edu/dl/html/j9mm.html
====================== 2 =================================
VarHandle是什么:https://www.cnblogs.com/teacherma/p/13471208.html
plain类型不确保内存可见性,opaque、release/acquire、volatile是可以保证内存可见的。
opaque保证程序执行顺序,但不保证其它线程的可见顺序。
release/acquire 保证程序执行顺序,setRelease确保前面的load和store不会被重排序到后面,但不确保后面的load和store重排序到前面;getAcquire确保后面的load和store不会被重排序到前面,但不确保前面的load和store被重排序。
volatile确保程序执行顺序,且保证变量之间不被重排序。
====================== 3 =================================
VarHandle get/setOpaque:https://stackoverflow.com/questions/56342141/varhandle-get-setopaque
主要表达的是,opaque特性在于没有因果,即使通过opaque读拿到了变量的opaque写的结果,但是也不能保证opaque写操作的前面的内容一定完成,也即是说相对于release和acqure模型,粒度和范围更更小了。如果,一个线程只关心变量操作的结果,不关心变量操作的前面的内容可以采用opaque模型,系统一定的一致性来获取更高的性能。
====================== 4 =================================
在Java 9时出现了VarHandle来部分替代java.util.concurrent.atomic 和sun.misc.Unsafe。
方法名 作用 说明
get 获取值 与普通变量取值一样,会重排、有不可见现象
set 设置值
getOpaque 获取值 对其保护的变量,保证其不重排和可见性,但不使用屏障,不阻碍其它变量
setOpaque 设置值
getAcquire 获取值 相当于get 之后加LoadLoad + LoadStore
setRelease 设置值 相当于set 之前加LoadStore + StoreStore
getVolatile 获取值 语义同volatile,相当于获取之后加LoadLoad + LoadStore
setVolatile 设置值 语义同volatile,相当于设置之前加LoadStore + StoreStore,设置之后加StoreLoad
compareAndSet 原子赋值 原子赋值,成功返回true,失败返回false
https://juejin.cn/post/6844904174669430797
https://www.debugger.wiki/article/html/1597930560364854
https://bugs.openjdk.java.net/browse/JDK-8152698
====================== 5 =================================
在Java 8之前,Java提供的底层编程接口有两种,一是JNI,一是Unsafe。相比JNI,Unsafe对底层操作系统的依赖更小点,但还是有问题。sun开头的包并非Oracle官方维护的API,Oracle还计划在未来的JDK版本中删除这些API。所以使用Unsafe的代码可能会有兼容性和移植性的问题。于是有了JEP 193,该提案主要就是针对这个问题,并且,它还提出了对象字段(或类静态字段)原子操作和不安全操作的标准化接口,这就是VarHandle。
https://www.cnblogs.com/teacherma/p/13471208.html
====================== 6 =================================
JUC整理笔记五之梳理Varhandle(下): https://blog.csdn.net/Jfound/article/details/106530913
浙公网安备 33010602011771号