首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于重新排序:为什么这段代码在使用易失性的情况下抛出RuntimeException?

关于重新排序:为什么这段代码在使用易失性的情况下抛出RuntimeException?
EN

Stack Overflow用户
提问于 2018-07-12 09:00:26
回答 1查看 101关注 0票数 5

公共类ReOrdering实现可运行的{ int 1、2、3、4、5、6;易失性int volaTile;@重载公共void (){ 1;2= 2;3= 3;volaTile = 92;int x=4;int y=5;int z=6;}} onetwothree的赋值可能会被重新排序,只要它们都发生在volatile编写之前。类似地,xyz语句可能会重新排序,因为volatile写入发生在所有语句之前。volatile操作通常称为内存屏障。在保证之前会发生这种情况,以确保volatile变量的读和写指令不会在内存屏障上被重新排序。 在保证之前发生的情况有另一个效果:当线程写入volatile变量时,所有其他变量--包括非挥发变量--在写入volatile变量之前由线程更改,也会被刷新到主内存。当线程读取volatile变量时,它还读取所有其他变量(包括非易失性变量),这些变量与volatile变量一起被刷新到主内存。

布鲁斯·埃克尔“关于Java 8”

我一定是误解了什么,因为这段代码不是这样工作的

代码语言:javascript
复制
public class Reordering {
    private int x;
    private volatile int y;

    public void writer() {
        x = 1;
        y = 2;
    }

    public void reader() {
        if (y == 2) {
            if(x == 0) {
                // X assignment is happens-before for
                // volatile Y assignment
                // so X can't be 0 when Y equals 2
                throw new RuntimeException();
            }

            x = 0;
            y = 0;
        }
    }

    public static void main(String[] args) {
        Reordering reordering = new Reordering();

        Thread thread = new Thread(() -> {
            while (true) {
                reordering.writer();
            }
        });

        thread.setDaemon(true);
        thread.start();

        while (true) {
            reordering.reader();
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-12 09:21:42

我认为,当作者刚刚设置了x=1时,当读取器已经在if块中(在变量赋值之前)时,问题就会发生:

代码语言:javascript
复制
reader             writer state
-----------------  ------ --------
stops before x=0          x=1, y=2
                   x=1    x=1, y=2
x=0                       x=0, y=2
y=0                       x=0, y=0
                   y=2    x=0, y=2
reader will throw
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51301372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档