《Java并发编程的艺术》 —3.4.2 volatile写-读建立的happens-before关系
【摘要】 本节书摘来自华章计算机《Java并发编程的艺术》一书中第3章,第3.4.2节,作者是方腾飞 魏鹏 程晓明。
3.4.2 volatile写-读建立的happens-before关系
上面讲的是volatile变量自身的特性,对程序员来说,volatile对线程的内存可见性的影响比volatile自身的特性更为重要,也更需要我们去关注。
从JSR-133开始(即从JDK5开始),volatile变量的写-读可以实现线程之间的通信。
从内存语义的角度来说,volatile的写-读与锁的释放-获取有相同的内存效果:volatile写和锁的释放有相同的内存语义;volatile读与锁的获取有相同的内存语义。
请看下面使用volatile变量的示例代码。
class VolatileExample {
int a = 0;
volatile boolean flag = false;
public void writer() {
a = 1; // 1
flag = true; // 2
}
public void reader() {
if (flag) { // 3
int i = a; // 4
……
}
}
}
假设线程A执行writer()方法之后,线程B执行reader()方法。根据happens-before规则,这个过程建立的happens-before关系可以分为3类:
1)根据程序次序规则,1 happens-before 2; 3 happens-before 4。
2)根据volatile规则,2 happens-before 3。
3)根据happens-before的传递性规则,1 happens-before 4。
上述happens-before关系的图形化表现形式如下。
图3-16 happens-before关系
在上图中,每一个箭头链接的两个节点,代表了一个happens-before关系。黑色箭头表示程序顺序规则;橙色箭头表示volatile规则;蓝色箭头表示组合这些规则后提供的happens-before保证。
这里A线程写一个volatile变量后,B线程读同一个volatile变量。A线程在写volatile变量之前所有可见的共享变量,在B线程读同一个volatile变量后,将立即变得对B线程可见。
本文统一用粗实线标识组合后产生的happens-before关系。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)