是否保证在另一个线程中看到一个线程中非易失性成员变量的赋值? [英] Are assignments to non-volatile member variables in one thread guaranteed to be seen in another thread?

查看:239
本文介绍了是否保证在另一个线程中看到一个线程中非易失性成员变量的赋值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Consider the Java example below. Notice that neither of the class member variables are declared to be volatile. If I am understanding the memory model and "happens before" rules correctly, a Java implementation could optimize the run() method so that it runs forever, even if another thread calls the stopNow() method. This can happen because there is nothing in the run() method that forces the thread to read the value of stop more than once. Is that correct? If not, why not?

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;
    }
}


推荐答案

那个可以被另一个线程修改,但这不是gurranteed。这也不是线程安全的。要使变量gurranteed从另一个线程中看到,您需要执行以下任何操作

that can be modified by another thread but this is not gurranteed. also this is not thread safe either. To make a variable gurranteed to see from another thread you need to do any of the following


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

Changes to fields made by one thread are guaranteed to be visible to other threads only under the following conditions:


  • 写入线程释放同步锁并随后获取读取线程相同的同步锁。

  • 如果一个字段被声明为volatile,那么写入它的任何值都会被刷新,并且在编写器

    线程执行之前由编写器线程可见任何进一步的记忆操作(即,为了目的,手头的
    立即刷新)。读取器线程必须在每次访问时重新加载volatile字段的$
    值。

  • 线程第一次访问对象的字段时,它会看到初始值字段或由
    写的其他一些线程的值。

  • 当一个线程终止时,所有写入的变量都被刷新到主内存。例如,如果一个线程使用Thread.join在
    另一个线程的终止上同步,则保证看到该线程产生的$
    效果(参见§4.3.2)。 / li>
  • A writing thread releases a synchronization lock and a reading thread subsequently acquires that same synchronization lock.
  • If a field is declared as volatile, any value written to it is flushed and made visible by the writer thread before the writer
    thread performs any further memory operation (i.e., for the purposes
    at hand it is flushed immediately). Reader threads must reload the
    values of volatile fields upon each access.
  • The first time a thread accesses a field of an object, it sees either the initial value of the field or a value since written by some other thread.
  • As a thread terminates, all written variables are flushed to main memory. For example, if one thread synchronizes on the termination of another thread using Thread.join, then it is guaranteed to see the
    effects made by that thread (see §4.3.2).

有用 SO线程

这篇关于是否保证在另一个线程中看到一个线程中非易失性成员变量的赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆