【翻譯十】volatile的含義

volatile的兩層語義

  • 保證共享變量的可見性緩存

  • 禁止進行指令重排序多線程

What does volatile do?

Volatile fields are special fields which are used for communicating state between threads. Each read of a volatile will see the last write to that volatile by any thread; in effect, they are designated by the programmer as fields for which it is never acceptable to see a "stale" value as a result of caching or reordering. The compiler and runtime are prohibited from allocating them in registers. They must also ensure that after they are written, they are flushed out of the cache to main memory, so they can immediately become visible to other threads. Similarly, before a volatile field is read, the cache must be invalidated so that the value in main memory, not the local processor cache, is the one seen. There are also additional restrictions on reordering accesses to volatile variables.app

Volatile字段是用來線程間交流狀態的特殊字段。線程對volatile的每次讀,都會看到其餘線程對它的最後一次寫,也就是說,volatile是隨時最新的。實際上,volatile被設計爲,在緩存或重排序中從不會失效的。JMM不容許編譯器和運行時將volatile字段分配到寄存器中,只能在寫入後,刷進主內存中,所以volatile字段的值老是對其餘字段可見的。類似的,在讀取前,會先清空本地處理器緩存,所以就能夠看到主內存中的最新值了。此外,JMM對volatile變量的訪問重排序也有限制。ui

Under the old memory model, accesses to volatile variables could not be reordered with each other, but they could be reordered with nonvolatile variable accesses. This undermined the usefulness of volatile fields as a means of signaling conditions from one thread to another.線程

在舊的內存模型下,對volatile變量的訪問,不能被重排序,但訪問非volatile變量卻能夠重排序。這破壞了volatile在多線程中做爲一個狀態信號的做用。翻譯

Under the new memory model, it is still true that volatile variables cannot be reordered with each other. The difference is that it is now no longer so easy to reorder normal field accesses around them. Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.設計

在新內存模型下,volatile變量一樣不能被重排序,區別在於,volatile變量周圍的普通字段也不會被輕易重排序。在內存的效果上,寫volatile與釋放監視器相同,讀volatile與獲取監視器相同。事實上,當對volatile及其餘字段的訪問在一塊兒的時候,因爲新內存模型更加嚴格的重排序約束,無論變量f是否volatile,當A線程寫f時,對於任何對其可見的變量,另外一條正在讀f的線程也能看到。rest

這部分翻譯很蛋疼,徹底不知道原文什麼意思,可是看過參考文章後,就立馬明白了。對volatile變量訪問的語句,前(後)面的不能重排序到後(前)面,可是前(後)面的仍是能夠重排序的。code

Here is a simple example of how volatile fields can be used:orm

如下是volatile字段的用法:

class VolatileExample {
      int x = 0;
      volatile boolean v = false;
      public void writer() {
        x = 42;
        v = true;
      }
    
      public void reader() {
        if (v == true) {
          //uses x - guaranteed to see 42.
        }
      }
    }

Assume that one thread is calling writer, and another is calling reader. The write to v in writer releases the write to x to memory, and the read of v acquires that value from memory. Thus, if the reader sees the value true for v, it is also guaranteed to see the write to 42 that happened before it. This would not have been true under the old memory model. If v were not volatile, then the compiler could reorder the writes in writer, and reader's read of x might see 0.

假設一條線程調用writer,另外一條調用reader。writer中v的寫入會將x的寫入發佈到內存中,而reader中v的讀取,會從內存中獲取x。所以,當reader看到v是true的時候,確定也會看到在v以前賦值的x,且x已是42了。若是v不是volatile,那麼writer中可能重排序,讀到的x就有可能爲0.

Effectively, the semantics of volatile have been strengthened substantially, almost to the level of synchronization. Each read or write of a volatile field acts like "half" a synchronization, for purposes of visibility.

實際上,volatile的語義被增強了,幾乎達到了同步的水平。爲了可見性,每一個volatile的寫入都至關於半個同步。

Important Note: Note that it is important for both threads to access the same volatile variable in order to properly set up the happens-before relationship. It is not the case that everything visible to thread A when it writes volatile field f becomes visible to thread B after it reads volatile field g. The release and acquire have to "match" (i.e., be performed on the same volatile field) to have the right semantics.

注意:爲了設置合適的happens-before關係,每條線程都應該訪問相同的volatile變量

參考文章

感受翻譯了半天仍是挺暈的,沒理解並且抱有疑問,因而又找到如下文章《深刻理解volatile關鍵字》,做者思路清楚,文中所述至關於這一系列的翻譯總結,且更加適合閱讀。

相關文章
相關標籤/搜索