1. 程式人生 > 其它 >【併發程式設計】-01-可見性、原子性、有序性

【併發程式設計】-01-可見性、原子性、有序性

01-可見性、原子性、有序性

源頭之一:快取導致的可見性問題

可見性:一個執行緒對共享變數的修改,另外一個執行緒能夠立刻看到,我們稱為可見性.

源頭之二:執行緒切換帶來的原子性問題

例如:count += 1,在cpu指令級別上

  • 指令 1:首先,需要把變數 count 從記憶體載入到 CPU 的暫存器;
  • 指令 2:之後,在暫存器中執行 +1 操作;
  • 指令 3:最後,將結果寫入記憶體(快取機制導致可能寫入的是 CPU 快取而不是記憶體)。

我們把一個或者多個操作在 CPU 執行的過程中不被中斷的特性稱為原子性。CPU 能保證的原子操作是 CPU 指令級別的,而不是高階語言的操作符。

源頭之三:編譯優化帶來的有序性問題

經典的例子:


public class Singleton {
  static Singleton instance;
  static Singleton getInstance(){
    if (instance == null) {
      synchronized(Singleton.class) {
        if (instance == null)
          instance = new Singleton();
        }
    }
    return instance;
  }
}

出現的問題:new 操作上,:

  • 分配一塊記憶體 M;
  • 在記憶體 M 上初始化 Singleton 物件;
  • 然後 M 的地址賦值給 instance 變數。

但是實際上優化後的執行路徑卻是這樣的:

  • 分配一塊記憶體 M;
  • 將 M 的地址賦值給 instance 變數;
  • 最後在記憶體 M 上初始化 Singleton 物件。
不要小瞧女程式設計師