java併發和高併發之線程安全性——有序性

一、有序性:

1、定義:java內存模型JMM中,允許編譯器和處理器對指令進行重排序,但是重排序過程不會影響到單線程程序的執行,卻會影響到多線程併發執行的正確性。

2、可以通過如下方案保證有序性:

volatile  關鍵字:保證一定的有序性

synchronized  和 Lock:保證每個時刻有一個線程執行同步代碼,相當於讓線程順序執行同步代碼。

Lock  :保證每個時刻有一個線程執行同步代碼,相當於讓線程順序執行同步代碼。

3、java 內存模型具備一定程度的先天性有序性,即在不通過任何外界保障的情況下,保證一定的有序性。通常稱爲happes-before原則,即先行發生原則(Happens-before原則):

》程序次序規則:一個線程內,按照代碼順序,書寫在前面的操作先行發生於書寫在後面的操作;

   注:對於該規則,個人理解,一段程序代碼的執行,在單線程中執行,看似是有序的,實際應該是代碼看似在按照程序書寫的順序邏輯進行執行,實際上是虛擬機可能會對程序在可分的邏輯上進行合理的重排序,但是最終的運行效果和正常順序執行結果一致。注,這裏純屬個人理解。該規則可以保證程序在單線程中執行順序的正確性,但無法保證在多線程中運行的準確性。

》鎖定規則:一個unLock操作先行發生於後面對同一個鎖的Lock操作。

  注:無論在單線程還是多線程中,必須先解鎖才能再加鎖。

》volatile 變量規則:對一個變量的寫操作發生於後面對這個變量的讀操作。

如果一個線程去讀,另一個線程去寫,則一定是寫操作發生於讀操作之前。

》傳遞規則:如果操作A 先行發生於操作B ,而操作B 又先行發生於操作C ,則可以得出操作A先行發生於操作C 。

》線程啓動規則:Thread對象的start()方法先行發生於此線程的每一個動作。

》線程中斷規則:對線程interrupt() 方法的調用先行發生於被中斷線程的代碼檢測到中斷事件的發生。

》線程終結規則:線程中所有的操作都先行發生於線程的終止檢測,我們可以通過Thread.join()方法結束、Thread.isAlive()的返回值手段檢測到線程已經終止執行。

》對象終結規則:一個對象的初始化完成先行發生於他的finalize() 方法的開始。

如果兩個操作的執行次序無法從happens-before的八個規則中推導出來,則無法保證他們的有序性,jvm就可以對他們進行指令重排序。

二、線程安全性總結;

》原子性:Atomic 包、CAS算法、synchronized、Lock

》可見性:synchronized 、volatile(如何保證可見性

》有序性:happens-before

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章