天天看點

設計模式之Singleton - 單态模式

本文介紹設計模式中的單态(Singleton)模式的概念,用法,以及實際應用中怎麼樣使用Singleton模式進行開發。

Singleton的概念

Singleton模式是一種對象建立型模式,使用Singleton模式,可以保證為一個類隻生成唯一的執行個體對象。也就是說,在整個程式空間中,該類隻存在一個執行個體對象。

其實,GoF對Singleton模式的定義是:保證一個類隻有一個執行個體存在,同時提供能對該執行個體加以通路的全局通路方法。

為什麼要使用Singleton模式呢?

在應用系統開發中,我們常常有以下需求:

- 在多個線程之間,比如servlet環境,共享同一個資源或者操作同一個對象

- 在整個程式空間使用全局變量,共享資源

- 大規模系統中,為了性能的考慮,需要節省對象的建立時間

等等

因為Singleton模式可以保證為一個類隻生成唯一的執行個體對象,是以這些情況,Singleton模式就派上用場了。

Singleton模式的實作

Singleton模式是設計模式中相對比較簡單的模式之一。了解以及使用方法都比較簡單。

Singleton模式有多個實作方法。但目前,每一種都存在或多或少的問題。

下面我們将給出幾種實作方法,同時對它們加以比較。

第一種方法:

這是一種最簡單的實作方法。但是一種相對有效的實作方法。現在,一般推薦這一種方法作為Singleton模式的實作方法。

//1)使用final關鍵字修改class,防止子類繼承

public final class Singleton {

    //2)Singleton自身唯一執行個體instance

    private static final Singleton instance = new Singleton();

    //3)private構造方法。防止外部調用者使用new建立新的執行個體

    private Singleton(){};

    //4)提供唯一執行個體的全局通路點

    public static Singleton getInstance(){

        return Singleton.instance;

    }

    ...

}

注意上述1),2),3),4)部分,這是Singleton模式實作的幾個關鍵。

我們注意到,這種方法沒有對instance = new Singleton()部分作同期化操作,但考慮到Singleton執行個體的生成隻是在最初被調用時才執行一次,如果我們在調用時适當處理一下,比如在程式的統一初期化時(SERVLET環境的情況下可以在容器被初始化時如SevletListener裡)調用一下Singleton,就不會存線上程安全問題。

第二種方法:

    private static Singleton instance;

    public static synchronized Singleton getInstance(){

        if(instance == null){

            instance = new Singleton();

        }

        return instance;

該方法把Singleton執行個體生成放到了getInstance方法裡,同時使用synchronized解決了線程安全問題。

但如果在高并發的應用系統中,大量的線程在調用getInstance時會受到阻塞,系統的性能将受到嚴重影響。

第三種方法:

            synchronized (this) {

                //double-check

                if(instance == null){

                    instance = new Singleton();

                }

            }

該方法也叫double-check(雙重檢查)方法,把線程同步synchronized放到隻會被執行一次的同步塊裡。該方法雖然解消了性能瓶頸問題,但該方法被指出并不是線程安全的(不同步的情況下引用類型不是線程安全的)。

第四種方法:

    private volatile static Singleton instance;

繼續閱讀