先行發生原則(Happens-before)

先行發生原則(Happens-Before)是判斷數據是否存在競爭、線程是否安全的主要依據。
先行發生是Java內存,模型中定義的兩項操作之間的偏序關係,如果操作A先行發生於操作B,那麼操作A產生的影響能夠被操作B觀察到。

Java內存模型中存在的天然的先行發生關係:

1. 程序次序規則:同一個線程內,按照代碼出現的順序,前面的代碼先行於後面的代碼,準確的說是控制流順序,因爲要考慮到分支和循環結構。

2. 管程鎖定規則:一個unlock操作先行發生於後面(時間上)對同一個鎖的lock操作。

3. volatile變量規則:對一個volatile變量的寫操作先行發生於後面(時間上)對這個變量的讀操作。

4. 線程啓動規則:Thread的start( )方法先行發生於這個線程的每一個操作。

5. 線程終止規則:線程的所有操作都先行於此線程的終止檢測。可以通過Thread.join( )方法結束、Thread.isAlive( )的返回值等手段檢測線程的終止。 

6. 線程中斷規則:對線程interrupt( )方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生,可以通過Thread.interrupt( )方法檢測線程是否中斷

7. 對象終結規則:一個對象的初始化完成先行於發生它的finalize()方法的開始。

8. 傳遞性:如果操作A先行於操作B,操作B先行於操作C,那麼操作A先行於操作C。

總結:一個操作“時間上的先發生”不代表這個操作先行發生;一個操作先行發生也不代表這個操作在時間上是先發生的(重排序的出現)。
時間上的先後順序對先行發生沒有太大的關係,所以衡量併發安全問題的時候不要受到時間順序的影響,一切以先行發生原則爲準。


發佈了65 篇原創文章 · 獲贊 34 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章