singlon = new SingleInstance() 這個(gè)動(dòng)作不是原子的,正常來(lái)說(shuō)按順序可以分為三步:1.申請(qǐng)一段內(nèi)存空間來(lái)保存新對(duì)象;2.調(diào)用構(gòu)造方法初始化這個(gè)新對(duì)象;3.將singlon變量引用指向這段將內(nèi)存地址。
使用volatile的原因是禁止指令重排。如果不用volatile,可能執(zhí)行順序是1-->3-->2。當(dāng)前一個(gè)線程執(zhí)行完3之后,singlon變量的指向已經(jīng)不為null(但其內(nèi)存空間還沒(méi)經(jīng)過(guò)2的初始化,該對(duì)象還是個(gè)半成品不應(yīng)該被使用),可能被后來(lái)的線程在最外層的if判斷中判斷成立并被返回使用。其他線程一旦使用了這個(gè)半成品對(duì)象的內(nèi)部字段,就會(huì)出現(xiàn)空指針。
由Synchronized的內(nèi)存可見性說(shuō)起在Java中,我們都知道關(guān)鍵字synchronized可以用于實(shí)現(xiàn)線程間的互斥,但我們卻常常忘記了它還有另外一個(gè)作用,那就是確保變量在內(nèi)存的可見性 - 即當(dāng)讀寫兩個(gè)線程同時(shí)訪...