單例模式如下:
需要volatile關鍵字的原因是,在並發情況下,如果沒有volatile關鍵字,在第5行會出現問題。
instance = new TestInstance();可以分解為3行偽代碼
a.memory = allocate() //分配內存
b. ctorInstanc(memory) //初始化對象
c. instance = memory //設置instance指向剛分配的地址
上面的代碼在編譯運行時,可能會出現重排序從a-b-c排序為a-c-b。在多線程的情況下會出現以下問題。當線程A在執行第5行代碼時,B線程進來執行到第2行代碼。假設此時A執行的過程中發生了指令重排序,即先執行了a和c,沒有執行b。那么由於A線程執行了c導致instance指向了一段地址,所以B線程判斷instance不為null,會直接跳到第6行並返回一個未初始化的對象。