設計模式之單例模式

optimise  v.表示樂觀,使優化
o歐弟 p婆婆  ti替  mi我  se蛇
歐弟的婆婆替我優化了貪吃蛇程序。
設計模式之單例模式

動機:
        有的時候一個類只有一個實例很重要,比如在一個系統裏應該只有一個window manager。通常情況下,單例模式被用來集中管理內部或者外部資源。並提供一個全局的訪問點。
目的:        確認一個類只有一個實例被創建。提供一個全局的訪問點去訪問該實例。
實現:    私有的構造函數和靜態公共的全局訪問點
class Singleton
{
    private static Singleton instance;
    private Singleton()
    {
        ...
    }
    public static synchronized Singleton getInstance()    //synchronized同步用來避免多線程創建多個實例
    {
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
    ...
    public void doSomething()
    {
        ...    
    }
}
public class MyRunable implements Runnable{
    @Override
    public void run() {
        System.out.println(Singleton.getInstance());
    }
}
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new MyRunable());
            thread.start();
        }
    }
適用和例子:
    一個類只能存在一個實例的時候用單例,通過全局的訪問點去訪問該實例,下面是一些例子:
Example 1: Logger Classes  日誌類
    單例被用來設計日誌類,日誌通過全局訪問點得到實例而不用每次去創建它。
Example 2; Configuration Classes 配置類
    單例被用來設計配置應用設置的配置類。通過用單例實現配置類,我們不僅提供全局的訪問點,而且保持
該實例作爲內存對象cache object。當這個類被實例化之後,這個單例就會在類的內部保存值。當這些值被從
數據庫或者文件中讀出來,這可以避免配置參數被使用的時候每次重新加載。
Example 3: Factories implemented as Singletons 用單例實現工廠模式
    假設我們設計一個在多線程環境中使用工廠模式通過它們的ids生成新對象的應用。如果這個工廠被實例化兩次在
兩個不同的線程,很可能產生兩個一樣的id產生兩個不同的對象。如果我們使用單例去實現這個工廠,就可以避免
這個問題。將抽象工廠或者工廠方法同單例模式一起使用是個通常的做法。
說明問題和解決問題:
使用多線程的線程安全。
    之前通過用synchronized修飾getInstance()方法實現線程的標準做法,但是不是最好的線程安全實現,因爲同步化(synchronized)是非常昂貴的,我們看到在通過同步實例化該對象的時候,我們沒必要再用synchronezed方法去檢查是否線程同步。
    所以最好的方法就是在一個非線程同步塊(unsynchronized bolck)中去檢查對象是否爲空,如果爲空,再從一個同步塊(synchronized block)中創建一個對象。這種做法稱之爲Double Locking Mechanism 雙鎖機制。
//Lazy instantiation using double locking mechanism.
class Singleton
{
    private static Singleton instance;
    private Singleton()
    {
    System.out.println("Singleton(): Initializing Instance");
    }
    public static Singleton getInstance()
    {
        if (instance == null)
        {
            synchronized(Singleton.class)
            {
                if (instance == null)
                {
                    System.out.println("getInstance(): First time getInstance was invoked!");
                    instance = new Singleton();
                }
            }            
        }
        return instance;
    }
    public void doSomething()
    {
        System.out.println("doSomething(): Singleton does something!");
    }
}


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