【发布时间】:2019-05-06 06:29:09
【问题描述】:
给定以下代码:
public class Test {
private volatile boolean a;
private volatile boolean b;
private void one () {
a = true;
System.out.println (b);
}
private void two () {
b = true;
System.out.println (a);
}
public static void main (String[] args) throws Exception {
Test s = new Test ();
Thread one = new Thread (s::one);
Thread two = new Thread (s::two);
one.start ();
two.start ();
one.join ();
two.join ();
}
}
是否保证(在 Java 内存模型下)至少一个线程打印true?
我知道在对 volatile 变量的写入和看到更新值的读取之间存在发生前的关系,但我似乎没有一个线程可以看到更新的值,尽管我不能不要让它发生。
【问题讨论】:
-
我认为它必须至少打印一个
true,尽管我实际上不会编写这样的代码。如果one打印false,那么它必须已经执行a=true;,所以另一个线程必须打印true。如果两个线程交错,它们都可以打印true,但我没有看到一条可以同时打印false的路径。 -
我没有看到这里的冲突。两者都没有办法被锁定,因为 volatile 变量只会被更新和释放,例如一旦
b = true完成,它会释放 b 上的锁,而不是在等待 a 被释放时保留它 -
我想你的问题可能会得到解答here
-
这不是捎带。我认为这里的症结在于
println是否可以在 volatile 的分配之上重新排序,我认为答案是“不”。 -
这就是我要说的。问题是,程序顺序是有保证的,并且只允许不违反程序顺序的相同结果的重新排序。由于在这里重新排序会产生不同的结果,我认为这是不允许的。不过,我很想在内存模型中找到更明确的规则。 @AndyTurner
标签: java concurrency volatile