整理內容---部分來自書籍,部分來自網絡 。
Happens-before 和 synchronizes-with是用來建立和理解Java 併發的基礎 。
- HAPPENS-BEFORE:這個關係用來指示“一段代碼在其他代碼開始執行前已經完全執行完畢”。
- SYNCHRONIZES-WITH:這個關係表示一個行爲在發生時,它首先把要操作的那些對象同主存同步完畢之後才繼續執行。
HAPPENS-BEFORE
HAPPENS-BEFORE:Java內存模型中定義的兩項操作之間的偏序關係,如果操作A先行發生於操作B,其實就是說在發生操作B之前,操作A產生的影響能被操作B觀察到。“影響”包括修改了內存中共享變量的值,發送了消息,調用了方法等。
- 程序次序規則:在一個線程內,按照代碼控制流順序,在前面的操作先行發生於後面的操作。
- 管程鎖定規則:一個unlock操作先行發生於後面對同一個鎖的lock操作。
- Volatile變量規則:對一個volatile變量的寫操作先行發生於後面對這個變量的讀操作。
- 線程啓動規則:Thread對象的start()方法先行發生於此線程的每個操作。
- 線程終止規則:線程中的所有操作都先行發生於對此線程的終止檢測。
- 線程中斷規則:對線程的interrupt()方法的調用先行發生於被中斷線程的代碼檢測中斷事件的發生。
- 對象終結過則:一個對象的初始化完成先行發生於它的finalize()方法的開始。
- 傳遞性:如果操作A先行發生於操作B,操作B現象發生於操作C,那麼就可以得出操作A先行發生於操作C的結論。
時間上的先後順序與先行發生原則之間基本上沒有太大的關係。所以,在衡量併發安全問題的時候不要受到時間順序的干擾,一切都以先行發生原則爲準。
SYNCHRONIZES-WITH
線程對變量的所有操作(讀取,賦值等)都必須在工作內存中進行,而不能直接讀寫主內存的變量。不同的線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成。線程不能直接爲主存中中字段賦值,它會將值指定給工作內存中的變量副本(assign),完成後這個變量副本會同步到主存儲區(store-write),至於何時同步過去,根據JVM實現系統決定.