2017-03-14 54 views
7

我與我的老師在java中關於volatile關鍵字有一點爭論。 那麼,是否可以說,當一個變量聲明爲volatilejava下引用揮發性關鍵字

這個變量的值將不會被線程本地緩存:所有 讀取和寫入操作將直接進入「主內存」。

我的老師的看法是:

volatile關鍵字承諾變量的值將 被保存在主存儲器。

有人能解決我們的衝突嗎?謝謝!

+0

這個問題可能會有所幫助:http://stackoverflow.com/questions/2423622/volatile-vs-static-in-java – niceman

+0

我相信volatile所做的一切就是所有線程都會看到變量的一個副本(而不是多個每個線程的副本),其中存儲的變量是我認爲的一個實現細節(你的老師可能是對的:)) – niceman

+0

答案可能取決於你是在爭論Java語言還是在談論某種特定的Java語言實現。在Java語言規範中沒有_cache_或_main memory_這樣的東西。在Java中有對象和字段和變量,'volatile'可以確保何時以及以何種順序更新由一個線程創建的變量對其他線程可見。 –

回答

9

對於關鍵字的確切含義,如volatile,請看Java語言規範,看官方的含義。

JLS paragraph 8.3.1.4解釋了volatile意味着:

的字段可以聲明波動,在這種情況下,Java內存模型確保所有線程看到一致的值的變量(§17.4)。

Paragraph 17.4解釋Java存儲器模型。內存模型爲程序中的每個語句之後數據發生的情況提供了一定的保證。

如果仔細研究,你會發現volatile意味着如果你寫入一個volatile變量,你可以保證其他線程將看到寫入的內容。在實踐中如何實施這是故意沒有說明的。它可以通過強制寫入主內存來實現,但JVM實現者可以自由選擇不同的,可能更有效的機制。

因此,嚴格來說,你的老師是對的。這並不一定意味着該值被寫入主存儲器;儘管實際上這可能是這種情況 - 但它取決於特定的JVM實現。

0

這裏不言而喻: https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.1.4 從Java 8 SE規範:

中的字段可被聲明揮發性的,在這種情況下,Java內存模型確保所有線程看到用於可變

一致的值

在「Java併發實踐」中描述了非常好的恕我直言。 https://jcip.net/也許你的圖書館裏有它?

+0

具體來說,語言規範沒有提到「主內存」或線程本地緩存。雖然:「所有實例字段,靜態字段和數組元素都存儲在堆內存中」 –

1

volatile所做的是忽略所有本地CPU緩存;或者等價地刷新包含要從主內存刷新的變量volatile的緩存行。因此,正如文檔所建議的那樣,它確保所有讀取直接從主存儲器讀取,並且所有寫入直接寫入主存儲器。

除此之外,volatile也有原子操作保證。它確保以該關鍵字爲前綴的變量將被讀取或寫入,就像它是單個指令一樣。 (正如相比之下,您不會擔心由2個線程寫入的64位長整數以及來自一個線程的第一個32位和來自另一個線程的第二個32位)。因此,在某些情況下,例如如果您在32位機器上使用64位長整數的volatile,那麼JVM可能需要做的不僅僅是「volatile」指令。還有一些文件在https://blogs.oracle.com/dave/entry/java_memory_model_concerns_on

給你的具體問題。

  • 在Java中讀取volatile時,它確保變量的值來自主存儲器。
  • 在Java中編寫volatile時,它確保將變量的值寫入主內存。

說了以上 - 這是從「邏輯」的角度。在現實中,現代CPU採用複雜的緩存策略,有時可以保證上述情況是真實的,而無需實際寫入主內存。然而,只有在實現與性能優化步驟完全相同的效果時才這樣做。但我認爲這超出了討論的範圍。

1

我只是引用兩段從文檔

first

的字段可以聲明波動,在這種情況下,Java內存模型 確保所有線程看到一致的值的變量 (第17.4節)。

second

存儲器模型描述的程序的可能行爲。一個 的實現可以自由生成任何它喜歡的代碼,只要所有的程序產生的執行結果都可以由內存模型預測出來,即 。

這爲執行者執行大量代碼轉換提供了很大的自由度,包括重新排序動作 並消除不必要的同步。


現在,如果你是指大部分的教程就votatile keyword in java,大多會提出同樣的事情,你的建議,即這個變量的值將不會被線程本地緩存:所有讀寫操作將直接進入「主內存」

但文檔不保證它。儘管它從不否認。它只是說這是possbbile行爲

所以我會說你的老師是對的。根據文檔(而不是文檔以外的大多數教程),揮發性關鍵字肯定是而不是承諾變量的值將保存在主內存中。

但是,這並不會讓你錯,這一切都取決於JVM的實現。