我正在阅读Paul Butcher的“七个星期内的七个并发模型”,在第2.2章中提供了示例代码“ puzzle.java”:
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(); } }
所以这是一个赛车条件。
然后说
想象一下,我们重写了run(),如下所示:
public void run() { while (!answerReady) Thread.sleep(100); System.out.println("The meaning of life is: " + answer); }
我们的程序可能永远不会退出,因为answerReady可能永远不会变成真实。
请问为什么?
如果我未能在书中清楚地解释这一点,请原谅我。我会在这里再试一次:-)
您需要识别的第一件事是,t2
只有当answerReady
变为时,循环才会退出true
。唯一将其设置为的true
是t1
。
因此,换句话说,t2
要退出,它需要查看所做的内存更改t1
。
问题是,除非代码正确同步,否则JVM无法保证一个线程所做的更改是否可被另一个线程看到。
由于此代码未正确同步(没有使用任何锁),因此JVM无法保证是否t2
会看到对的更改answerReady
。因此,循环可能永远不会退出。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句