1. 程式人生 > >Java volatile keyword

Java volatile keyword

產生 內部 重排序 pre 指令重排 ron cache style 拷貝

前言:

用在多線程,同步變量。線程為了提高效率,將某個成員(A)變量拷貝了一份(B)。線程中對A的訪問事實上訪問的是B。僅僅在某些動作時才進行A和B的同步。因此存在A和B不

一致的情況。volatile就是用來避免這個中情況的。volatile告訴jvm,它所修飾的變量不保留拷貝,直接訪問主內存中的A。

在Java內存模型中,有main memory,每一個線程也

有自己的memory(寄存器).為了性能,一個線程會在自己的memory中保持要訪問的變量的副本。

這樣就會出現同一個變量在某個瞬時,在一個線程的memory中的值可能與另

一個線程memory中的值,或者main memory中的值不一致的情況。

一個變量聲明為volatile,就意味著這個變量是隨時會被其它線程改動的。因此不能將它cache在線程memory中。

1.特性:

volatilekeyword確保了應用中的可視性。假設你將一個域聲明為volatile,那麽僅僅要這個域產生了寫操作,那麽全部的讀操作都能夠看到這個改動。

2. 原子性:

volatile修飾的變量不同意線程內部緩存和重排序。即直接改動內存。所以對其它線程是可見的。但volatile僅僅能讓被它修飾的內容具有可見性,但不能保證它具有原子性。

僅僅會影響可見性,不會影響原子性。

3.其它:

1) 保證了不同線程對這個變量進行操作時的可見性,即一個線程改動了某個變量的值,這新值對其它線程來說是馬上可見的。

2) 禁止進行指令重排序。

4.實現機制:

觀察增加volatilekeyword和沒有增加volatilekeyword時所生成的匯編代碼發現,增加volatilekeyword時,會多出一個lock前綴指令。lock前綴指令實際上相當於一個內存屏障(也

稱內存柵欄)。內存屏障會提供三個功能:

1) 它確保指令重排序時不會把其後面的指令排到內存屏障之前的位置,也不會把前面的指令排到內存屏障的後面;即在運行到內存屏障這句指令時。在它前面的操作已全

部完畢。

2) 它會強制將對緩存的改動操作馬上寫入主存。

3) 假設是寫操作。它會導致其它CPU中相應的緩存行無效。

5.通常volatile必須具備下面兩個條件:

1) 對變量的寫操作不依賴於當前值。

2) 該變量沒有包括在具有其它變量的不變式中。

Java volatile keyword