在接下來的敘述裏我首先會說明happens-before規則是幹什麼用的,然後用一個簡單的小程序說明happens-before規則
一、happens-before規則
我們編寫的程序都要經過優化後(編譯器和處理器會對我們的程序進行優化以提高運行效率)纔會被運行,優化分爲很多種,其中有一種優化叫做重排序,重排序需要遵守happens-before規則,不能說你想怎麼排就怎麼排,如果那樣豈不是亂了套。
happens-before部分規則如下:
1、程序順序規則:一個線程中的每個操作happens-before於該線程中的任意後續操作
2、監視器鎖(同步)規則:對於一個監視器的解鎖,happens-before於隨後對這個監視器的加鎖
注1:爲什麼是部分happens-before原則,因爲這篇文章是讓你理解happens-before原則,我會盡量讓你專注在這件事情上不被其他的所影響
注2:程序順序規則中所說的每個操作happens-before於該線程中的任意後續操作並不是說前一個操作必須要在後一個操作之前執行,而是指前一個操作的執行結果必須對後一個操作可見,如果不滿足這個要求那就不允許這兩個操作進行重排序
二、例:下面的方法的功能是計算一個長方形面積
public double rectangleArea(double length , double width){
double leng;
double wid;
leng=length;//A
wid=width;//B
double area=leng*wid;//C
return area;
}
上面的操作在運行之前編譯器和處理器可能會進行優化
在程序中
A happens-before B
B happens-before C
A happens-before C //happens-before具有傳遞規則
根據happens-before規則我們來分析重排序後可能產生的結果
因爲A happens-before B,所以A操作產生的結果leng一定要對B操作可見,但是現在B操作並沒有用到length,所以這兩個操作可以重排序,那A操作是否可以和C操作重排序呢,如果A操作和C操作進行了重排序,因爲leng沒有被賦值,所以leng=0,area=0*wid也就是area=0;這個結果顯然是錯誤的,所以A操作是不能和C操作進行重排序的(這就是注2中說的前一個操作的執行結果必須對后羿操作可見,如果不滿足這個要求就不允許這兩個操作進行重排序)
THE END!!!
下一篇文章我會詳細講述爲什麼使用雙重檢查鎖的單例類會失敗,敬請期待