我知道,Java中volatile變量的用途是寫入這些變量對其他線程立即可見。我也意識到一個同步塊的效果之一就是將線程本地內存刷新到全局內存。刷新線程局部內存到全局內存是什麼意思?
我從來沒有完全理解在這種情況下對'線程本地'內存的引用。我明白,只存在於堆棧上的數據是線程本地的,但是當談論堆中的對象時,我的理解變得朦朧。
我希望得到以下幾點意見:
當一臺機器上有多個處理器上執行,並刷新線程本地存儲僅僅指的是CPU緩存到內存的沖洗?
在單處理器機器上執行時,這是否意味着什麼?
如果堆有可能在兩個不同的內存位置(每個都由不同的線程訪問)有相同的變量,在什麼情況下會出現這種情況?這對垃圾收集有什麼影響?虛擬機如何積極地做這種事情?
(編輯:添加問題4)退出同步塊時刷新了什麼數據?這是線程在本地的一切嗎?它只是在同步塊內寫入的嗎?
Object x = goGetXFromHeap(); // x.f is 1 here Object y = goGetYFromHeap(); // y.f is 11 here Object z = goGetZFromHead(); // z.f is 111 here y.f = 12; synchronized(x) { x.f = 2; z.f = 112; } // will only x be flushed on exit of the block? // will the update to y get flushed? // will the update to z get flushed?
總的來說,我認爲想了解是否線程局部手段內存只有一個CPU物理訪問或者如果由VM進行邏輯線程本地堆分配?
任何指向演示或文檔的鏈接都將非常有幫助。我花了很多時間研究這個問題,雖然我發現了很多很好的文獻,但我一直無法滿足我對線程本地存儲器的不同情況定義的好奇心。
非常感謝。
感謝您的意見。我其實很熟悉逃生分析,它開始與'線程本地'混淆。我想請問兩個後續問題: 1.如果編譯器已經證明一個對象是線程本地的,並且該對象存在於堆的線程局部區域中,那麼爲什麼要寫入該對象內部一個同步塊需要刷新?從CPU緩存到線程本地堆區域的刷新只能被寫入的線程觀察到?這是線程切換處理器,並開始執行一個不同的CPU緩存? – 2010-03-22 21:32:47
2. JVM有可能在堆上的兩個單獨的內存位置同時存在一個對象嗎?如果是這樣,在什麼情況下會出現這種情況? – 2010-03-22 21:33:22
1.「同步」意味着「全部」的沖洗。 'synchronized'有一個參數,這個參數是獲取鎖的實例,但是Java內存模型要求來自線程的整個內存視圖受到內存障礙的限制。現在,如果JVM可以證明它不需要刷新對象,因爲沒有其他線程可以看到它(並且「未轉義對象」是很好的候選對象),那麼JVM就可以在「as if」規則(JVM只要結果與Java抽象機器無法區分就可以完成它所希望的任何事情)。 – 2010-03-23 12:16:14