1. 程式人生 > >設計模式篇(2)--單例模式

設計模式篇(2)--單例模式

0.引言

單例模式是設計模式最普遍也最常見的模式之一。它是用於產生一個物件的具體例項,確保系統中一個類只產生一個例項。

適用場景:系統只需要一個例項物件,如系統要求提供一個唯一的序列號生成器或資源管理器,或者需要考慮資源消耗太大而只允許建立一個物件。客戶呼叫類的單個例項只允許使用一個公共訪問點,除你該公共訪問點,不能通過其他途徑訪問該例項。

優點:

      提供了對唯一例項的受控訪問

      由於在系統記憶體中只存在一個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷燬的物件單例模式無疑可以提高系統的效能

      允許可變數目的例項

缺點:

      由於單利模式中沒有抽象層,因此單例類的擴充套件有很大的困難。

      單例類的職責過重,在一定程度上違背了“單一職責原則”

      濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為的單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位;如果例項化的物件長時間不被利用,系統會認為是垃圾而被回收,這將導致物件狀態的丟失。

在Java中這樣的行為能帶來對於頻繁使用的物件,可以省略new操作花費的時間,這對於那些重量級的物件而言,是非常可觀的一筆系統開銷;由於new操作的次數減少,因而對系統記憶體的使用頻率也會降低,這將減輕GC壓力,縮短GC停頓時間。

1.餓漢模式

public class EHSingleton{
    private EHSingleton(){}
    private static EHSingleton instance=new EHSingleton();
    public static EHSingleton getInstance(){
        return instance;
    }
}
//這種方式優點在於無須考慮多執行緒訪問問題,可以確保例項的唯一性,但是由於它在類第一次初始化的時候被建立,而不是getInstance()方法第一次被呼叫的時候。

2.懶漢模式

//執行緒不安全
public class LHSingleton{
    private LHSingleton(){}
    private static LHSingleton instance=null;
    public static LHSingleton getInstance(){
        if(instance==null){
            instance=new LHSingleton();
        }
        return instance;
    }
}
//執行緒安全,效率低百分之99不需要同步
public class LHSingleton{
    private LHSingleton(){}
    private static LHSingleton instance=null;
    public static synchronized LHSingleton getInstance(){
        if(instance==null){
            instance=new LHSingleton();
        }
        return instance;
    }
}

3.靜態內部類

//這種方式實現的單例同時有前兩種方式的優點
public class StaticSingleton{
    private StaticSingleton(){
    }
    private static class SingletonHolder{
        private final static StaticSingleton instance =new StaticSingleton();
    }
    public static StaticSingleton getInstance(){
        return SingletonHolder.instance;
    }
}