4-5 執行緒安全性-有序性與總結
阿新 • • 發佈:2018-12-14
有序性
一個執行緒觀察其他執行緒中的指令執行順序,由於指令重排序的存在,該觀察結果一般雜亂無序。 JMM允許編譯器和處理器對指令進行重排序,但是重排序過程不會影響到單執行緒程式的執行,卻會影響到多執行緒併發執行的正確性。 可以通過volatile、synchronized、lock保證有序性。 Happens-before原則 先天有序性,即不需要任何額外的程式碼控制即可保證有序性,java記憶體模型一個列出了八種Happens-before規則,如果兩個操作的次序不能從這八種規則中推倒出來,則不能保證有序性。
- 程式次序規則:一個執行緒內,按照程式碼執行,書寫在前面的操作先行發生於書寫在後面的操作。
- 鎖定規則:一個unLock操作先行發生於後面對同一個鎖的lock操作
- volatile變數規則:對一個變數的寫操作先行發生於後面對這個變數的讀操作
- 傳遞規則:如果操作A先行發生於操作B,而操作B又先行發生於操作C,則可以得出操作A先行發生於操作C
- 執行緒啟動原則:Thread物件的start()方法先行發生於此執行緒的每一個動作
- 執行緒中斷規則:對執行緒interrupt()方法的呼叫先行發生於被中斷執行緒的程式碼檢測到中斷事件的發生
- 執行緒終結規則:執行緒中所有的操作都先行發生於執行緒的終止檢測,我們可以通過Thread.join()方法結束、Thread.isAlive()方法返回值手段檢測到執行緒已經終止執行
- 物件終結規則:一個物件的初始化完成先行發生於他的finalize()方法的開始
第一條規則要注意理解,這裡只是程式的執行結果看起來像是順序執行,雖然結果是一樣的,jvm會對沒有變數值依賴的操作進行重排序,這個規則只能保證單執行緒下執行的有序性,不能保證多執行緒下的有序性。