23種設計模式之單例模式(java 實現)

一、概述書接上回,之前我我們講到原型設計模式。這次我們談談單例模式。單例模式是最喜聞樂見的設計模了,因爲是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。他保證只有一個實例而且提供給全局使用

二、類圖:

    

三、實現

   類圖十分簡單隻要保證類能提供一個實例就可以,既然要保證只提供一個實例。那麼要將構造方法設計爲私有屬性。就如Effective JAVA中的一種方式提供一個靜態工廠方法返回對象實例即可。其實實現單例模式的有挺多種的,這讓我想起《孔乙己》裏面一句話“你知道茴豆的茴字有幾種寫法嗎” 那麼單例模式有多少中寫法呢?答案是6種


1.懶漢模式(線程不安全 )

通過提供一個靜態的對象instance,利用private權限的構造方法和getInstance()方法來給予訪問者一個單例。缺點是,沒有考慮到線程安全,可能存在多個訪問者同時訪問,並同時構造了多個對象的問題。之所以叫做懶漢模式 * 主要是因爲此種方法可以非常明顯的lazy loading。 加鎖可以實現線程安全

public class LazySingleton {
	
	private static LazySingleton instance;
	
	private LazySingleton() {
		
	}
	
	public static LazySingleton getInstance() {
		if(instance==null) {
			instance = new LazySingleton();
		}
		return instance;
	}

}


2.懶漢模式(線程安全 )

通過對靜態工廠方法加鎖實現

public class LazySingleton {
	
	private static LazySingleton instance;
	
	private LazySingleton() {
		
	}
	
	public static synchronized LazySingleton getInstance() {
		if(instance==null) {
			instance = new LazySingleton();
		}
		return instance;
	}

}


3 餓漢模式

直接在運行這個類的時候進行一次loading,之後直接訪問。顯然,這種方法沒有起到lazy loading的效果但是不需要用鎖就實現線程安全,考慮到前面提到的和靜態類的對比,這種方法只比靜態類多了一個內存常駐而已。

public class HungerSingleton {
	
	private static HungerSingleton instance = new HungerSingleton();
	
	private HungerSingleton() {
		
	}
	
	public static HungerSingleton getInstance() {
		return instance;
	}

}


4 靜態內部類模式

靜態內部類不會在單例加載時就加載,而是在調用getInstance()方法時才進行加載,達到了類似懶漢模式的效果,而這種方法又是線程安全的。

public class SingletonDemo {
	
	private static class SingletonHolder{
		private static SingletonDemo instance=new SingletonDemo();
	}
	
	private SingletonDemo() {
		
	}
	
	public static SingletonDemo getInstance(){
        return SingletonHolder.instance;
    }

}


5 雙重校驗法

理論上雙重校驗鎖法是線程安全的,並且,這種方法實現了lazyloading。

簡述一下加載類的過程 :STEP 1. 線程A訪問getInstance()方法,因爲單例還沒有實例化,所以進入了鎖定塊。STEP 2. 線程B訪問getInstance()方法,因爲單例還沒有實例化,得以訪問接下來代碼塊,而接下來代碼塊已經被線程1鎖定。STEP 3. 線程A進入下一判斷,因爲單例還沒有實例化,所以進行單例實例化,成功實例化後退出代碼塊,解除鎖定。STEP 4. 線程B進入接下來代碼塊,鎖定線程,進入下一判斷,因爲已經實例化,退出代碼塊,解除鎖定。STEP 5. 線程A獲取到了單例實例並返回,線程B沒有獲取到單例並返回Null


public class SingletonCheck {
	private volatile static SingletonCheck instance;
    private SingletonCheck(){
    }
    public static SingletonCheck getInstance(){
        if(instance==null){
            synchronized (SingletonCheck.class){
                if(instance==null){
                    instance=new SingletonCheck();
                }
            }
        }
        return instance;
    }
}

6枚舉法

public enum SingletonEnum {
	INSTANCE;
    public void otherMethods(){
        System.out.println("Something");
    }
}

總結 以上這些就是單例模式的實現方法我的實現代碼在網盤:http://pan.baidu.com/s/1eRQKXuM


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章