Java多線程之有序性


有序性

在Java內存模型中,允許編譯器和處理器對指令進行重排序,但是重排序過程不會影響單線程執行的結果,會影響到多線程並發執行結果的正確性

volatile,synchronized,Lock通過volatile,synchronized,Lock保證一定的有序性,synchronized,Lock保證每一時刻只有一個線程可以執行同步代碼塊,相當於讓線程順序執行同步代碼,從而保證有序性。另外,JVM具備一些先天的有序性,即不需要額外的手段就能保證有序性,即Happens-before原則,如果兩個操作的執行次序,沒有辦法通過Happens-before原則推導出來,虛擬機進行隨意的重排序,那么久不能保證有序性。

Happens-before

1.如果一個操作Happens-before另外一個操作,那么第一個操作的執行結果相對第二個操作可見,並且第一個操作的執行順序在第二個操作之前執行。

2.兩個操作之間存在Happens-before關系,並不意味着一定要按Happens-before原則制定的順序執行。如果重排序之后的執行結果與Happens-before關系執行的結果一致,那么這種重排序就不非法。

下面是Happens-before的規則

  • 程序次序規則:一個線程內,按照代碼順序,書寫在前面的操作先行發生於書寫在后面的操作;
  • 鎖定規則:一個unLock操作先行發生於后面對同一個鎖額lock操作;
  • volatile變量規則:對一個變量的寫操作先行發生於后面對這個變量的讀操作;
  • 傳遞規則:如果操作A先行發生於操作B,而操作B又先行發生於操作C,則可以得出操作A先行發生於操作C;
  • 線程啟動規則:Thread對象的start()方法先行發生於此線程的每個一個動作;
  • 線程中斷規則:對線程interrupt()方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生;
  • 線程終結規則:線程中所有的操作都先行發生於線程的終止檢測,我們可以通過- - Thread.join()方法結束、Thread.isAlive()的返回值手段檢測到線程已經終止執行;
  • 對象終結規則:一個對象的初始化完成先行發生於他的finalize()方法的開始;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM