一、概述書接上回,之前我我們講到原型設計模式。這次我們談談單例模式。單例模式是最喜聞樂見的設計模了,因爲是 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;
}
}
通過對靜態工廠方法加鎖實現
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;
}
}
靜態內部類不會在單例加載時就加載,而是在調用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