一、概述
1.Java內存模型(Java Memory Model或JMM)裏定義的happens-before 規則指的是:用于描述多線程中變量讀寫等不同操作之間的內存可見性,若操作 A happens-before 操作 B ,那麽操作 A 的結果對操作 B 可見。
2.happens-before 規則分爲單線程和多線程的情況:
1)單線程下的 happens-before :
因爲單線程內只有一份工作內存,不存在數據一致性的問題,所以字節碼的先後執行順序天然符合happens-before關系。
在程序中靠前的字節碼 happens-before 靠後的字節碼,即靠前
的字節碼執行完之後的操作結果對靠後的字節碼可見。但是,這並不意味著前者一定在後者之前執行。若後者不依賴前者的運行結果,那麽它們可能會被重排序。
2)多線程下的 happens-before:
多線程中由于每個線程都有共享變量的工作內存副本,如果沒有對共享變量做同步處理,線程1更新A共享變量的值之後,線程 2 開始執行操作 B,此時操作 B 不一定能看見變量 A 被更新後的值。
二、詳細
Java 內存模型實現了下述支持 happens-before 關系的操作:
1. 程序順序規則: 一個線程內,按照代碼順序,書寫在前面的操作 happens-before 書寫在後面的操作。
2. 鎖規則: 對一個鎖的 unlock 操作 happens-before 後面對同一個鎖的 lock 操作。
3. volatile 變量規則: 對一個volatile變量的寫操作 happens-before 後面對這個變量的讀操作。volatile關鍵字保證變量在不同線程之間的可見性。
4. 傳遞規則: 若操作 A happens-before 操作 B,而操作 B 又 happens-before 操作 C,則操作 A happens-before 操作 C。
5. 線程啓動規則:Thread 對象的 start()方法 happens-before 此線程內的任何代碼的執行。
6. 線程中斷規則: 對線程 interrupt()方法的調用 happens-before 被中斷線程的代碼檢測到中斷事件的發生(通過靜態方法Thread.interrupted()或實例方法Thread.isInterrupted()調用)。
7. 線程終結規則: 線程中所有的操作都 happens-before 線程的終止檢測,我們可以通過 Thread.join()方法等待線程結束、Thread.isAlive()的返回值爲false等手段檢測到線程是否已經終止執行。
8. 對象終結規則: 一個對象的構造方法執行完畢 happens-before 它的 finalize()方法的開始執行。
微風不燥,陽光正好,你就像風一樣經過這裏,願你停留的片刻溫暖舒心。
我是程序員小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等編程技術的技巧經驗分享),若作品對您有幫助,請關注、分享、點贊、收藏、在看、喜歡,您的支持是我們爲您提供幫助的最大動力。
歡迎關注。助您在編程路上越走越好!