現代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