【发布时间】:2016-09-04 02:05:56
【问题描述】:
我有以下代码:
private volatile boolean run = true;
private Object lock =new Object();
…………
Thread newThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println(Thread.currentThread().getName()
+ " run:" + run);
System.out.println(Thread.currentThread().getName()
+ " setting run to false");
run = false;
System.out.println(Thread.currentThread().getName()
+ " run:" + run);
}
}});
newThread.start();
while(true) {//no synchronization, so no coordination guarantee
System.out.println(Thread.currentThread().getName() + "* run: "+run);
if(run == false) {
System.out.println(Thread.currentThread().getName() + "** run: "+run+"\nExiting...");
System.exit(0);
}
}
which generates the following output:
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
Thread-0 setting run to false
Thread-0 run:false
main* run: true <- what causes this???
main** run: false
Exiting...
我试图理解为什么在主线程中出现 main* run: true 的异常,因为 run 是一个易失性字段,并且根据 Java 内存模型规范,易失性写入Thread-0 中的 mainthread 应该立即可见。我知道Thread-0 中的同步在这里是无关紧要的,但我对 volatile 的这种行为感到困惑。我在这里想念什么?
另一个更奇怪的运行产生了这个:
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main** run: false
Exiting...
Thread-0 run:false
或者这种行为是意料之中的,如果是,为什么?谢谢。
编辑:正如 cmets 中所问的,我正在使用我有时但并非总是看到的预期输出更新帖子:
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
main* run: true
Thread-0 setting run to false
main* run: true
main* run: true
main* run: true
Thread-0 run:false
main** run: false
Exiting...
也就是说,我不想看到:
main* run: true
出现在之后
Thread-0 run:false
或
main** run: false
Exiting...
出现在之前
Thread-0 run:false
【问题讨论】:
-
请制作一个mvce。想要运行您发布的代码的人不应该必须从不完整的 sn-ps 重构它。
-
@NathanHughes:什么是 mvce?
-
此场景中还有另一个共享资源:
System.out。 -
mvce = 最有价值的代码示例。
-
@MikeSamuel:你介意解释一下吗?
标签: java multithreading java.util.concurrent java-memory-model