原子性
操作對于其他線程是不可分割的(參見數(shù)據(jù)庫的事務(wù))
updateHostInfo(ip,port){
setIP(ip)
setPort(port)
}
上述操作就是非原子性操作
實現(xiàn)原子性的兩種方法:
1.使用鎖(lock),軟件鎖;
2.利用處理器提供的CAS(Compare-And-Swap)指令,硬件鎖;
Java對于基本類型變量,long/double的寫操作不保證原子性。使用volatile關(guān)鍵字保證原子性
可見性
一個線程對共享變量的修改應(yīng)該讓其他后續(xù)會使用該變量的線程得到更新的結(jié)果。 對于不同處理器的更新,可能僅僅被寫入了高速緩存而不是內(nèi)存,這對于其他處理器是不可見的,需要進行緩存同步。使用volatile關(guān)鍵字保證。
JLS Java語言規(guī)范保證,
父線程在啟動子線程之前對共享變量的更新對于子線程是可見的;
一個線程終止后該線程對共享變量的更新對于調(diào)用該線程join方法的線程是可見的;
有序性
重排序
編譯器和處理器對源代碼在單線程運行環(huán)境下的優(yōu)化。
指令重排序:源代碼與程序順序不一致(編譯器 javac)、程序順序與執(zhí)行順序不一致(JIT,處理器)。
存儲子系統(tǒng)重排序:處理器感知順序與上述三種順序不一致(高速緩存,寫緩沖器)。
上下文切換和資源征用。