1.什么是指令重排
程序指令的執(zhí)行順序有可能和代碼的順序不一致,這個過程就稱之為指令重排。
2.指令重排的作用
JVM能根據(jù)處理器的特性,充分利用多級緩存,多核等進(jìn)行適當(dāng)?shù)闹噶钪嘏判颍钩绦蛟诒WC業(yè)務(wù)運行的同時,充分利用CPU的資源,發(fā)揮最大的性能!
由于指令重排的特性,為了保證程序在多線程的條件下運行結(jié)果能夠與單一線程下一致,引入了Happens-Before規(guī)則。也就是說,Happens-Before規(guī)則主要是用來確保并發(fā)情況下數(shù)據(jù)的正確性。
3.Happens-Before的含義
如果動作B要看到動作A的執(zhí)行結(jié)果,無論A/B是否在同一個線程中,那么A/B必須滿足happens-before規(guī)則。
4. happens-before規(guī)則
1)如果ActionA和ActionB屬于同一個線程,那么就說明ActionA happens-before ActionB。
2)如果ActionA是unlock操作,而ActionB是lock操作,那么ActionA happens-before ActionB。
3)如果A是對volatile變量的寫操作,ActionB是對同一個變量的讀操作,那么ActionA happens-before ActionB。
4)線程的啟動Action happens-before 該線程上的其他動作。
5)線程中任何Action都 happens-before 任何其他線程檢測到該線程已經(jīng)結(jié)束、Thread.join調(diào)用成功返回,Thread.isAlive返回false。
6)一個線程調(diào)用另一個線程的interrupt一定發(fā)生在另一個線程中斷之前。
7)一個對象的構(gòu)造函數(shù)結(jié)束一定發(fā)生在兌現(xiàn)finalizer之前。
8)ActionA發(fā)生在ActionB之前,ActionB發(fā)生在ActionC之前,則ActionA一定發(fā)生在ActionC之前。
ActionA happends-before ActionB,記作hb(ActionA,ActionB)。
5. JMMA(Java Memory Model Action)
Java模型動作,一個Action包含,變量讀取、變量寫、監(jiān)視器枷鎖、釋放鎖、線程啟動(start)、線程等待(join)。