Java volatile keyword
前言:
用在多線程,同步變量。線程為了提高效率,將某個成員(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