为什么有时效果(在一个线程中)不会对其他线程可见?

时间:2016-07-06 07:24:48

标签: multithreading concurrency

我在七周内阅读了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 可能永远不会出现   变成现实。

我可以问为什么?

1 个答案:

答案 0 :(得分:2)

如果我没有在书中清楚地解释这一点,请原谅我。我将在这里再试一次: - )

您需要认识到的第一件事是t2中的循环只会在answerReady变为true时退出。唯一可以设置为true的是t1

因此,换句话说,要让t2退出,需要查看t1对内存的更改。

问题在于JVM使无法保证关于一个线程所做的更改是否被另一个线程看到,除非代码正确同步。

由于此代码未正确同步(没有任何锁使用),JVM无法保证t2是否会看到对answerReady的更改。所以循环可能永远不会退出。