java 中的重排序和内存屏障的疑问,希望解答?!!
邀请啊,我java水平一般,4,5不会到3前面的。volatile变量法则:对volatile域的写入操作happens-before于每一个后续对同一个域的读写操作。只是说线程1的flag = true;之前所有操作包括非volatile变量,在线程2的flag2=flag之后的所有代码都可见。i初始为0;例如线程1i = 1;非volatileflag = true;线程2boolean flag2=flag;int j = i;如果flag = true;先执行了,那么j一定为1. 反之不一定,不过很难观察到。。。个人感觉研究这么深这玩意没啥必要,像回字四种写法,反正我也写不出doglea那样的juc,只知道volatile好用不贵就行了。哈哈哈。仔细看了一下他这个内容,感觉不一样,看我之前的问题,x86下是没有读操作的内存屏障的。jvm1.8对于volatile做操作的时候,写操作会插入lock指令,读操作lock指令被注释掉了? - Java
■网友
先说结论,下面再给出分析。结论1:语句4和语句5可以被重排序到语句3之前结论2:但是语句1和语句2不能被重排到语句3之后
分析如下:
语句3是个volatile变量写操作。而volatile关键字会禁止volatile变量写操作与该操作之前的任何读、写操作进行重排序。因此,结论2成立。
volatile上述效果的实现是由编译器在voaltile写操作之前插入一个release barrier(相当于loadstore+storestore)实现。而这个barrier并不对volatile写操作之后的操作其作用,因此结论1成立。
有关volatile的重排序规则,可参考:http://gee.cs.oswego.edu/dl/jmm/cookbook.html
【更新】
评论里有同学问到具体什么样的语句可以被重排序。这个问题的答案总的来说是:
存在数据依赖关系的两条语句(确切的说是指令)不能够被重排序存在控制依赖关系的两条语句(确切的说是指令)可以够被重排序具体可以参考我的新书(Java多线程编程实战指南(核心篇),预计2017年4月中旬上市):
【java 中的重排序和内存屏障的疑问,希望解答?!!】
■网友
volatile变量法则:对volatile域的写入操作happens-before于每一个后续对同一个域的“读写”操作。题主给出的文章中的这句大概是文章作者手滑了。JSR133写的是:A write to a volatile ?eld happens-before every subsequent read of that volatile.然后回过头来回答题主的问题:是的,4、5可以重排序到3之前,但是1、2不能重排序到3之后。
推荐阅读
- 鄂温克冬季马赛-30℃极寒开赛:寒冬中的火热派对
- 大雪@大雪腌肉 适当进补 今日大雪
- |电商事业中的“闪光少年”
- dart这编程语言现在发展怎么样了,语法与Java,c#很相似,甚至更简洁
- hadoop中的mapreduce链接(mapreduce chaining)怎样避免中间文件的产生
- 经观汽车|日系车企中的“异类”?东风日产将导入e-POWER技术大干增程式混动 | 经观汽车
- 中年|这些东西,比你想象中的还要大得多!
- Java工程师和C++工程师在工作上有啥区别哪个更适合自身发展
- 请问杨毅微博中的这两人是谁
- 某些公司招聘要求中的精通mysql是啥程度