我在七周内阅读了Paul Butcher"七种并发模型"它提供了示例代码" puzzle.java"在第2.2章:
mysql
所以这是一个竞赛条件。
然后它说,
想象一下,我们按如下方式重写了run():
ThreadsLocks/Puzzle/src/main/java/com/paulbutcher/Puzzle.java
public class Puzzle {
static boolean answerReady = false;
static int answer = 0;
static Thread t1 = new Thread() {
public void run() {
answer = 42;
answerReady = true;
}
};
static Thread t2 = new Thread() {
public void run() {
if (answerReady) System.out.println("The meaning of life is: " + answer);
else System.out.println("I don't know the answer");
}
};
public static void main(String[] args) throws InterruptedException {
t1.start(); t2.start(); t1.join(); t2.join();
} }
我们的计划可能永远不会退出,因为 answerReady 可能永远不会出现 变成现实。
我可以问为什么?
答案 0 :(得分:2)
如果我没有在书中清楚地解释这一点,请原谅我。我将在这里再试一次: - )
您需要认识到的第一件事是t2
中的循环只会在answerReady
变为true
时退出。唯一可以设置为true
的是t1
。
因此,换句话说,要让t2
退出,需要查看t1
对内存的更改。
问题在于JVM使无法保证关于一个线程所做的更改是否被另一个线程看到,除非代码正确同步。
由于此代码未正确同步(没有任何锁使用),JVM无法保证t2
是否会看到对answerReady
的更改。所以循环可能永远不会退出。