單例模式幾種寫法,安全 不安全 懶漢 餓漢


單例模式幾種寫法,安全 不安全 懶漢 餓漢

單例模式在平常中運用較多,而且在面試中更是被經常提及
單例模式有幾個重點是懶漢模式,餓漢模式,線程安全,線程不安全


這個是最普通的單例模式,這個是懶漢式,線程不安全

//這個是普通的單例模式
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變量。這是因為在第一次加載到內存中的就會被初始化,所以創建實例本身是線程安全的。

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**;
	}

}

這是目前最好的解法,既是線程安全又無其他的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM