现代CPU并不总是按照更新的顺序将数据写入内存,例如,如果运行伪代码(假设变量总是存储在内存中以方便操作);
a = 1
b = a + 1
...的CPU很可能写b
内存写入a
内存之前。只要你在一个单独的线程中运行,这不是一个真正的问题,因为运行上面代码的线程一旦完成赋值就永远不会看到任何一个变量的旧值。多线程是另一回事,你会认为下面的代码会让另一个线程拿起你沉重的计算的价值;
a = heavy_computation()
b = DONE
...其他线程做...
repeat while b != DONE
nothing
result = a
虽然是在完成标志可以在内存中的结果之前设置的问题是存储到内存中,因此其他线程在计算结果被写入内存之前可能会读取内存地址a的值。
同样的问题会 - 如果Thread.start
和Thread.join
没有保证“之前发生” - 给你喜欢代码的问题;
a = 1
Thread.start newthread
...
newthread:
do_computation(a)
...因为a
在线程启动时可能没有存储到内存的值。
因为你几乎总是需要新的线程能够使用您在开始之前,初始化数据,Thread.start
有保证了“之前发生”,即,具有呼叫Thread.start
之前被更新保证数据可用到新线程。同样的事情发生在Thread.join
,其中由新线程写入的数据保证对终止后加入它的线程可见。
它只是使线程更容易。
'发生之前关系'意味着这些语句集合保证在另一组语句之前执行。因此,在第一种情况下,导致启动新线程的语句与新启动的线程将执行的语句之间具有发生之前的关系。这些语句所做的任何更改都将对线程执行的语句可见。 – 2013-04-27 06:23:11
我觉得这个网页很有用:http://preshing.com/20130702/the-happens-before-relation/它给出了A和B之间“发生之前”关系与B之前实际发生的A不同的例子。 – 2015-02-11 17:40:19