1. 程式人生 > 其它 >java中的單例模式

java中的單例模式

技術標籤:java技術java設計模式單例模式

目錄

第一.餓漢式

第二.懶漢式

第三.靜態內部類 推薦

總結


程式開發中有時候某些物件我們只需要一個,如:執行緒池、快取、對話方塊等等,對於這類物件我們只能有一個例項,如果我們製造出多個例項,就會導致很多問題產生。但是我們怎樣才能保證一個類只有一個例項並且能夠便於訪問?這裡我們想到了全域性變數,全域性變數確實是可以保證該類可以隨時訪問,但是它很難解決只有一個例項問題。最好的辦法就是讓該自身來負責儲存它的唯一例項。通過上面簡單介紹,我們可以對單例模式有一個簡單的認識。所謂單例模式就是確保某一個類只有一個例項,並且提供一個全域性訪問點。從上面可以看出單例模式有如下幾個特點:1.它只有一個例項;2.它必須要自行例項化;3.它必須自行向整個系統提供訪問點。

單例的建立模式有很多種,下面的文章中我只介紹三種方式,多餘的就不說了!

第一.餓漢式

/**
 * 餓漢式天生就是執行緒安全的,可以直接用於多執行緒而不會出現問題
 * @author Administrator
 *
 */
public class Single1 {
    private static  final Single1 single1=new Single1();

    private Single1() {
    }
    //靜態工廠方法
    public   static  Single1 getInstance(){
        return single1;
    }
}

第二.懶漢式

懶漢式本身是非執行緒安全的,為了實現執行緒安全有幾種寫法,分別是上面的下面的getInstance2和getInstance3,在資源載入和效能方面有些區別。

/**
 * 懶漢式本身是非執行緒安全的,為了實現執行緒安全有幾種寫法,分別是上面的下面的getInstance2和getInstance3,在資源載入和效能方面有些區別。
 * 還有一種方法是靜態內部類,也是執行緒安全的
 */
public class Single2 {
    private  static  Single2 single2=null;

    Single2() {
    }

    /**
     * 執行緒不安全
     * @return
     */
    public  static Single2 getInstance(){
        if(single2==null){
             single2=new Single2();
        }
        return single2;
    }

    /**
     * 在getInstance方法上加同步(效能較差)
     * @return
     */
    public  static synchronized  Single2 getInstance2(){
        if(single2==null){
            single2=new Single2();
        }
        return single2;
    }

    /**
     * 雙重檢查鎖定(DCL 雙檢查鎖機制)推薦
     * @return
     */
    public   static Single2 getInstance3(){
        if(single2==null){
            synchronized (Single2.class){
                if(single2==null){
                    single2=new Single2();
                }
            }
        }
        return single2;
    }
}

第三.靜態內部類 推薦

利用靜態內部類在原始類初始化的時候不載入的特性(只有在呼叫的時候才會載入),可以實現單例模式。

/**
 * 靜態內部類 推薦
 */
public class Single3 {
    private static Logger logger= LoggerFactory.getLogger(Single3.class);
    private  static  class CrateSingle{
        private static final  Single3 single3=new Single3();
    }

    private  Single3() {
       
    }

    public   static  final Single3  getInstance(){
        return  CrateSingle.single3;
    }
}

總結

優點
一、節約了系統資源。由於系統中只存在一個例項物件,對與一些需要頻繁建立和銷燬物件的系統而言,單例模式無疑節約了系統資源和提高了系統的效能。
二、因為單例類封裝了它的唯一例項,所以它可以嚴格控制客戶怎樣以及何時訪問它。

缺點
一、由於單例模式中沒有抽象層,因此單例類的擴充套件有很大的困難。
二、單例類的職責過重,在一定程度上違背了“單一職責原則”。(因為單例設計模式,在程式碼getInstance書寫的過程中,有些程式碼是比較複雜的,而且會伴有一些初始化的函式,會造成該類的多種初始化或者組裝程式碼的書寫。)

下列幾種情況可以使用單例模式。
一、系統只需要一個例項物件,如系統要求提供一個唯一的序列號生成器,或者需要考慮資源消耗太大而只允許建立一個物件。
二、客戶呼叫類的單個例項只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該例項。