[英]Are assignments to non-volatile member variables in one thread guaranteed to be seen in another thread?
Consider the Java example below. 考虑下面的Java示例。 Notice that neither of the class member variables are declared to be
volatile
. 请注意,这两个类成员变量都没有声明为
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. 如果我正在理解内存模型并且“之前发生”规则正确,Java实现可以优化
run()
方法,以便它永远运行,即使另一个线程调用stopNow()
方法。 This can happen because there is nothing in the run()
method that forces the thread to read the value of stop
more than once. 这可能发生,因为
run()
方法中没有任何内容强制线程多次读取stop
的值。 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;
}
}
that can be modified by another thread but this is not gurranteed. 可以被另一个线程修改,但这不是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
要使变量gurranteed从另一个线程中看到,您需要执行以下任何操作
Changes to fields made by one thread are guaranteed to be visible to other threads only under the following conditions:
只有在以下条件下,才能保证一个线程对字段的更改对其他线程可见:
- 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
如果一个字段被声明为volatile,那么写入它的任何值都会被写入之前的写入器线程刷新并使其可见
thread performs any further memory operation (ie, for the purposes线程执行任何进一步的内存操作(即,用于此目的
at hand it is flushed immediately).在手边它立即被冲洗)。 Reader threads must reload the
读者线程必须重新加载
values of volatile fields upon each access.每次访问时的volatile字段的值。
- 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
例如,如果一个线程使用Thread.join在另一个线程的终止上同步,则保证看到
effects made by that thread (see §4.3.2).该线程产生的影响(见§4.3.2)。
That's correct. 那是对的。 That's one of the reasons you might want to use
volatile
. 这是您可能想要使用
volatile
的原因之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.