一个线程中对非易失性成员变量的赋值是否保证在另一个线程中可见?

2023-11-23

考虑下面的 Java 示例。请注意,两个类成员变量都没有声明为volatile。如果我正确理解内存模型和“发生在”规则之前,Java 实现可以优化run()方法,使其永远运行,即使另一个线程调用该方法stopNow()方法。发生这种情况是因为里面没有任何东西run()强制线程读取值的方法stop不止一次。那是对的吗?如果没有,为什么不呢?

class Example implements Runnable {
    boolean stop = false;
    int value = 0;

    public void stopNow() {
       stop = true;
    }

    public int getValue() {
        return value;
    }

    @Override
    public void run() {
        // Loop until stop is set to true.
        while (!stop) {
            ++value;
        }
        return;
    }
}

可以由另一个线程修改,但这不是保证。这也不是线程安全的。要保证变量可以从另一个线程查看,您需要执行以下任一操作

保证对一个线程所做的字段更改可见 其他线程仅在以下条件下:

  • 写入线程释放同步锁,读取线程随后获取相同的同步锁。
  • 如果一个字段被声明为易失性,则写入该字段的任何值都会在写入器之前由写入器线程刷新并使其可见
    线程执行任何进一步的内存操作(即,出于以下目的
    在手边,它会立即被冲洗)。读取器线程必须重新加载
    每次访问时易失性字段的值。
  • 线程第一次访问对象的字段时,它会看到该字段的初始值或自写入以来的值 其他一些线程。
  • 当线程终止时,所有写入的变量都会刷新到主内存。例如,如果一个线程在终止时进行同步 另一个线程使用 Thread.join,那么保证会看到
    该线程产生的效果(参见§4.3.2)。

helpful 所以线程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一个线程中对非易失性成员变量的赋值是否保证在另一个线程中可见? 的相关文章

随机推荐