sychronized與volatile區別?

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區別:

  • 都具備可見性
  • 使用方面上,volatile:變量,synhronized:方法,變量
  • volatile本質是在告訴jvm當前變量在寄存器(工做內存)中的值是不肯定的,須要從主存中讀取; synchronized則是鎖定當前變量,只有當前線程能夠訪問該變量,其餘線程被阻塞住。
  • volatile不會阻塞線程,synchronized會組賽線程
  • volatile標記的變量不會被編譯器優化,synchronized的會被優化
  • 單個volatile變量的讀/寫具備原子性,但相似於volatile++這種複合操做不具備原子性。synchronized具備原子性
相關文章
相關標籤/搜索