摘要:線程執行與變量可見性的關系什么是的關系的關系是保證一個線程執行的操作結果對不同線程中的另一個操作可見。執行寫入和讀取到內存的兩個線程可以在時鐘時間方面與其他操作保持一致,但可能看不到彼此一致的更改內存一致性錯誤,除非它們有關系。
Java 線程執行與變量可見性的 happen-before 關系 什么是 happen-before 的關系
happen-before 的關系是保證一個線程執行的操作結果對不同線程中的另一個操作可見。
Happens-before 定義程序中所有操作的部分排序。為了保證執行操作Y的線程可以看到操作X的結果(X和Y是否出現在不同的線程中),X和Y之間必然存在一個先發生的關系。在沒有happen-before 排序的情況下在兩個操作之間,JVM可以根據需要自由重新排序(JIT編譯器優化)。
happen-before 的不僅僅是"時間"中的動作重新排序,而且還保證了對內存的讀寫順序。執行寫入和讀取到內存的兩個線程可以在時鐘時間方面與其他操作保持一致,但可能看不到彼此一致的更改(內存一致性錯誤),除非它們有happen-before 關系。
如何建立 happen-before 關系?以下是發生之前的規則:
單線程規則:單個線程中的每個操作都發生在該程序順序中稍后出現的該線程中的每個操作之前。
監視器鎖定規則:監視器鎖定(退出同步方法/塊)上的解鎖發生 - 在每次后續獲取同一監視器鎖定之前。
易失性變量規則:在對該相同字段的每次后續讀取之前發生對易失性字段的寫入。易失性字段的寫入和讀取具有與進入和退出監視器(讀取和寫入時的同步塊)類似的內存一致性效果,但實際上沒有獲取監視器/鎖定。
線程啟動規則:線程上的 Thread.start() 調用發生在啟動線程中的每個操作之前。假設線程A通過調用threadA.start() 生成一個新線程B. 在線程B的run方法中執行的所有操作都將看到線程A調用threadA.start() 方法,之前(僅在線程A中)發生在它們之前。
線程連接規則:線程中的所有操作都發生在任何其他線程從該線程上的連接成功返回之前。假設線程A通過調用threadA.start() 生成一個新線程B,然后調用threadA.join() 。線程A將在 join() 調用時等待,直到線程B的run方法完成。在join方法返回后,線程A中的所有后續操作都將看到線程B的run方法中執行的所有操作都發生在它們之前。
傳遞性:如果A發生在B之前,B發生在C之前,那么A發生在C之前。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75687.html
摘要:舉個例子,在多線程不使用環境中,每個線程會從主存中復制變量到緩存以提高性能。保證了變量的可見性關鍵字解決了變量的可見性問題。在多線程同時共享變量的情形下,關鍵字已不足以保證程序的并發性。 volatile 關鍵字能把 Java 變量標記成被存儲到主存中。這表示每一次讀取 volatile 變量都會訪問計算機主存,而不是 CPU 緩存。每一次對 volatile 變量的寫操作不僅會寫到 ...
摘要:這個規則比較好理解,無論是在單線程環境還是多線程環境,一個鎖處于被鎖定狀態,那么必須先執行操作后面才能進行操作。線程啟動規則獨享的方法先行于此線程的每一個動作。 1. 指令重排序 關于指令重排序的概念,比較復雜,不好理解。我們從一個例子分析: public class SimpleHappenBefore { /** 這是一個驗證結果的變量 */ private st...
摘要:當線程執行完后進入狀態,表示線程執行結束。其中和表示兩個線程。但要注意,讓出并不表示當前線程不執行了。關鍵字其作用是防止指令重排和使線程對一個對象的修改令其他線程可見。 JMM特性一覽 Java Memory Model的關鍵技術點都是圍繞著多線程的原子性、可見性和有序性來建立的。因此我們首先需要來了解這些概念。 原子性(Atomicity) 原子性是指一個操作是不可中斷的。即使是在多...
閱讀 1887·2021-11-15 11:46
閱讀 1077·2021-10-26 09:49
閱讀 1819·2021-10-14 09:42
閱讀 3374·2021-09-26 09:55
閱讀 827·2019-08-30 13:58
閱讀 1024·2019-08-29 16:40
閱讀 3462·2019-08-26 10:27
閱讀 601·2019-08-23 18:18