保證一個類僅有一個執行個體:單例模式

來源:互聯網
上載者:User

情境:微軟的windows xp作業系統,ctrl+alt+del鍵都會彈出一個windows工作管理員(這時不關閉這個工作管理員),繼續ctrl+alt+del鍵還是一個windows工作管理員。鑒於本人水平有限,上面的情境舉例可能不合適,但是很接近一個基本的設計模式:單例模式。Code is cheap.下面用c#代碼類比出一個類似工作管理員的建立:

Code
using System;

/// <summary>
/// Singleton 單例模式
/// </summary>
public class WindowsTaskManager
{
    private static WindowsTaskManager wtm;
    private WindowsTaskManager()
    {
    }
    public static WindowsTaskManager CreateSingleWtm()
    {
        if (wtm==null)
        {
            wtm = new WindowsTaskManager();
        }
        return wtm;
    }
}

/// <summary>
/// 用戶端調用
/// </summary>
public class Client {
    static void Main(string[] args)
    {
        WindowsTaskManager myWtm = WindowsTaskManager.CreateSingleWtm();
        WindowsTaskManager myWtm1 = WindowsTaskManager.CreateSingleWtm();
        if (myWtm==myWtm1)
        {
            Console.WriteLine("兩個對象是相同的執行個體.");
        }
    }
}

上面建立執行個體的基本思想是new一個對象的時候,判斷靜態類變數是否已經有執行個體,建構函式私人,這樣外部代碼不能直接new來執行個體化對象。這是因為我們都知道所有類都有建構函式,不編碼寫建構函式則系統預設產生無參數的構造方法,但如果有顯式定義的構造方法,預設的就會失效。ps:在定義可序列化的類的時候,預設建構函式是必須的,所以如果你顯式定義了一個帶參數的構造方法,一定不能忘記要再寫一個沒有參數的構造方法。
好了,上面的代碼ms已經簡單的實現了對唯一執行個體的受控訪問。不過在多線程的程式中,上面的代碼會有可能建立多個執行個體的。給進程加把鎖,用lock解決一下:Code
using System;
using System.Threading;
/// <summary>
/// Singleton 
/// </summary>
public class WindowsTaskManager
{
    private static WindowsTaskManager wtm;
    private static readonly object syncRoot = new object();// 程式運行時建立一個靜態唯讀進程輔助對象
    private WindowsTaskManager()
    {
    }
    public static WindowsTaskManager CreateSingleWtm()
    {
        lock (syncRoot)
        {
            if (wtm == null)
            {
                wtm = new WindowsTaskManager();
            }
        }
        return wtm;
    }
}

上面那種做法可以建立單一執行個體,可是每次調用建立方法時,都要lock,影響效能,有一種雙重鎖定的方法:Code
using System;
using System.Threading;
/// <summary>
/// Singleton  雙重鎖定
/// </summary>
public class WindowsTaskManager
{
    private static WindowsTaskManager wtm;
    private static readonly object syncRoot = new object();// 程式運行時建立一個靜態唯讀進程輔助對象
    private WindowsTaskManager()
    {
    }
    public static WindowsTaskManager CreateSingleWtm()
    {
        if (wtm == null) //當wtm為空白時,如果這時有兩個線程同時調用CreateSingleWtm方法
        {
            lock (syncRoot)
            {
                if (wtm == null) // 很關鍵,沒有這個判斷,進入的兩個線程就可以建立兩個執行個體了
                {
                    wtm = new WindowsTaskManager();
                }
            }
        }
        return wtm;
    }
}

最後再看一個所謂的餓漢式單例類:Code
using System;
using System.Threading;
/// <summary>
/// Singleton  sealed防止派生增加執行個體
/// </summary>
public sealed class WindowsTaskManager 
{
    private static readonly WindowsTaskManager wtm=new WindowsTaskManager();
    private WindowsTaskManager()
    {
    }
    public static WindowsTaskManager CreateSingleWtm()
    {
        return wtm;
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.