【併發程式設計】-01-可見性、原子性、有序性
阿新 • • 發佈:2021-07-28
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 物件。