public class Singleton {
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if (Objects.isNull(instance)) {
synchronized (Singleton.class) {
if (Objects.isNull(instance)) {
instance = new Singleton();
}
}
}
return instance;
}
}
先說說加synchronized關鍵字原因 , 如果兩個線程執行時候 , 都獲取到instance , 都爲null , 就會同時實例化 , 這就導致結果不是同一個實例了.
然後就是鎖裏面的判斷 , ab線程都讀取到這個instance對象爲null , a先搶到鎖進入實例化 , 實例化完釋放鎖 , 由於b此時instance對象是null , 所以拿着鎖又進行實例化, 這就導致結果又不是同一個實例了.
接着就是最外層的判斷 , 主要是在instance被實例化外, 爲了不讓其他線程繼續等待拿到鎖再判斷 , 直接在最外層判斷可以優化線程, 節省時間
最後就是volatile 關鍵字, 是爲了防止指令重排序 , 做到一旦實例化就馬上將數據加載到內存 , 避免更多線程進入第一層判斷, 主要也是優化的作用. 至於防止指令重排序可以自己去百度查下.
面試的時候 , 如果面試官讓你手寫單例 , 基本上就是爲了考察你懶漢式 , 把這個寫上完美通關 !