“嗨,阿米戈!”

“有一個很大的話題——Java 內存模型。基本上,您還不必了解它,但了解它會很有幫助。”

“為了消除所有潛在的問題,Java 改變了它的內存管理機制。現在內存不再簡單地分為線程的本地緩存和全局內存——這種機制甚至更好。”

“而且更複雜!”

“是的,更好,更複雜。就像飛機。坐飛機比走路好,但更複雜。我會盡量簡單地解釋新情況。”

“這就是他們想出的。一種用於同步本地線程內存的機制,稱為‘happens-before’,被添加到代碼中。發明了幾個規則/條件。當滿足這些條件時,內存同步或更新到當前狀態。

“這是一個例子:”

命令 線程 1 線程 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
線程正在等待互斥量被釋放

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

“這些條件之一是獲取已釋放的互斥量。如果釋放並重新獲取互斥量,則內存將在獲取之前同步。線程 2 將看到變量 x 和 y 的‘最新’值,即使你不會宣布它們不穩定。”

“多麼有趣!這些條件有很多嗎?”

“夠了——這裡有一些同步記憶的條件:”

  • “在單個線程中,任何命令都發生在源代碼中跟隨它的任何操作之前。”
  • “鎖的釋放發生在獲得同一個鎖之前。”
  • “在同一監視器上輸入同步塊/方法 之前,會發生同步塊/方法的退出。”
  • “將易失性字段寫入內存發生在從內存中讀取相同的易失性字段之前。”
  • “Thread 對象的 run 方法的結束髮生在join() 方法結束或 isAlive() 方法在同一線程中的對像上返回 false 之前。”
  • “對 Thread 對象的 start() 方法的調用發生在run() 方法在同一線程中的對像上啟動之前。”
  • “構造函數的結束髮生此類的 finalize() 方法開始之前。”
  • “對 interrupt() 方法的調用發生在線程確定已調用此方法之前,因為拋出 InterruptedException 或使用 isInterrupted() 或 interrupted() 方法。”

“所以,這一切比我想像的要復雜一點?”

“是的,有點複雜……”

“謝謝你,Rishi。我會考慮的。”

“這個話題你不用太在意,總有一天你會自己明白的。現在,你還是先了解一下基礎知識,而不是鑽到密林裡去。 Java 機器的內部運作。Java 9 將發布,然後一切都會再次改變。”

“O_o。是的......有些事情最好不要知道。”