單例模式在日常中運用較多,並且在面試中更是被常常說起
單例模式有幾個重點是懶漢模式,餓漢模式,線程安全,線程不安全
這個是最普通的單例模式,這個是懶漢式,線程不安全面試
//這個是普通的單例模式 public class Singleton{ private static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ if (instance === null) { instance = new Singleton(); } return instance; } }
懶漢式,線程安全類型安全
//這個是線程安全的單例模式 //這個在調用的時候回鎖住整個方法,效率不是很好 public class Singleton{ private static Singleton instance = null; private Singleton(){ } public static synchronized getInstance(){ if (instance === null) { instance = new Singleton(); } return instance; } }
雖然這個是線程安全,可是效率不是很好,由於在任什麼時候候只有一個線程能調用getInstance()方法。
下面咱們就使用雙重檢驗鎖來解決這個問題。
雙重檢驗鎖是對同步塊加鎖的方法。爲何會稱爲雙重檢驗,由於有兩次對 instance == null的檢查,一次中同步塊中一次中同步塊外部。
爲何在同步塊內還要再檢驗一次?由於可能會有多個線程一塊兒進入同步塊外的 if,若是在同步塊內不進行二次檢驗的話就會生成多個實例了。線程
//這個是線程安全的是效率比較好的 public class Singleton{ private static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ if (instance == null) { synchronized(Singleton.class){ if (instance == null) { instance = new Singleton(); } } } return instance; } }
上面的不是都是懶漢模式的,下面咱們來介紹一下關於餓漢模式的
餓漢模式 static final field 這種方法也是很簡單,只須要將單例的實例聲明爲static何final變量。這是由於在第一次加載到內存中的就會被初始化,因此建立實例自己是線程安全的。code
public class Singleton{ //類加載時就初始化 private static final Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }
靜態內部類 stat nested class內存
//懶漢式的靜態內部類 public class Singleton{ private static class SingletonInner{ private static final Singleton INSTANCE = new Singleton(); } private Singleton{ } private static final Singleton getInstance(){ return SingletonInner.INSTANCE**strong text**; } }
這是目前最好的解法,既是線程安全又無其餘的問題。get