【发布时间】:2015-09-07 00:49:18
【问题描述】:
public class GuardedBlock {
private boolean guard = false;
private static void threadMessage(String message) {
System.out.println(Thread.currentThread().getName() + ": " + message);
}
public static void main(String[] args) {
GuardedBlock guardedBlock = new GuardedBlock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
guardedBlock.guard = true;
threadMessage("Set guard=true");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
threadMessage("Start waiting");
while (!guardedBlock.guard) {
//threadMessage("Still waiting...");
}
threadMessage("Finally!");
}
});
thread1.start();
thread2.start();
}
}
我正在通过 Java Essentials 教程学习并发。去守卫的街区并试图测试它。有一件事我无法理解。
虽然循环是无限的,但如果你取消注释 threadMessage 行一切正常。为什么?
【问题讨论】:
-
你到底想做什么?
guard的更改如果不是 volatile 将不会对其他线程可见。 -
当您注释掉该行时,您的 while 循环中就没有任何东西了,Java 足够聪明,可以忽略整个 while 循环。所以,它和没有 while 循环一样好。
-
一切正常是什么意思。它打印还在等待吗?那么最后?
-
把
guard改成volatile guard还能用吗?忙等待循环也很糟糕,我不建议您使用它们。考虑改用wait和notify。 -
@hagrawal:这不可能。如果是这样,OP 将不会遇到无限循环。相反,正如 akhil_mittal 所说,
guard不是volatile。所以它的值不能保证在线程之间同步。添加threadMessage行必须触发某种内存屏障,这恰好有助于同步线程对guard值的视图。但这是非常不可靠的行为。
标签: java multithreading