volatile的特性:java
對單個變量的讀/寫能夠當作鎖對單個變量所作的同步。jvm
class VolatileFeaturesExample { volatile long vl = 0L; // 使用volatile聲明64位的long型變量 public void set(long l) { vl = l; // 單個volatile變量的寫 } public void getAndIncrement () { vl++; // 複合(多個)volatile變量的讀/寫 } public long get() { return vl; // 單個volatile變量的讀 } }
class VolatileFeaturesExample { long vl = 0L; // 64位的long型普通變量 public synchronized void set(long l) { // 對單個的普通變量的寫用同一個鎖同步 vl = l; } public void getAndIncrement () { // 普通方法調用 long temp = get(); // 調用已同步的讀方法 temp += 1L; // 普通寫操做 set(temp); // 調用已同步的寫方法 } public synchronized long get() { // 對單個的普通變量的讀用同一個鎖同步 return vl; } }
可見性。對一個volatile變量的讀,老是能看到(任意線程)對這個volatile變量最後的寫入。優化
原子性:對任意單個volatile變量的讀/寫具備原子性,但相似於volatile++這種複合操做不具備原子性。線程
volatile寫/讀的內存語義:code
當讀一個volatile變量時,JMM會把該線程對應的本地內存置爲無效。線程接下來將從主內存中讀取共享變量。內存
經過把寫線程修改的結果寫入主存中,設置其餘線程本地內存包含的值設置爲無效,所以其餘線程須要從新從主存讀取來保證數據的一致性。rem
對volatile變量寫入與讀取的過程,形式上相似線程間的通訊。get
sychronized:編譯器
鎖釋放與volatile寫有相同的內存語義,鎖獲取與volatile讀有相同的內存語義。同步
sychronized與volatile區別: