2009-09-16 51 views
3
public class MySingletonClass 
{ 
    public MySingletonClass() 
    { 
    _mySingletonObj = Instance(); 
    } 

    public static MySingletonClass Instance() 
    { 
    if (_mySingletonObj == null) 
    { 
     lock (typeof(lockObject)) 
     { 
     if (_mySingletonObj == null) 
      _mySingletonObj = new MySingletonClass(); 
     } 
    } 
    return _mySingletonObj ; 
    } 
} 

MySingletonClass _myObj = new MySingletonClass(); 

使用公有構造函數的單例行爲..?帶公共構造函數的單例模式

感謝

+0

爲什麼你會喜歡這樣做的呀? – 2009-09-16 09:03:08

+5

我認爲這段代碼導致死鎖和遞歸構造函數調用 - >堆棧溢出。 – 2009-09-16 09:07:55

+0

這段代碼充滿了問題,實際上並沒有作爲單例使用,由於公共構造函數,正如奧利弗所指出的,這也會導致堆棧溢出。 – 2009-09-16 09:15:09

回答

14

不,這不是一個單 - 任何人都可以創建它的多個實例。 (撇開已經引發的堆棧溢出問題,以及您不安全地使用雙重檢查鎖定的事實)。

單例類型的一個顯着特徵是它可以防止自身的多個實例從未被修建。

從維基百科文章Singleton Pattern

在軟件工程中,將單 圖案是一種設計模式是用於限制 類的實例化到一個對象 。

Ward Cunningham's pattern repository

單身是二 基本屬性的組合:

  • 保證一個類僅有一個實例
  • 提供一個全局訪問點吧

顯然你的單身人士不能同時滿足這兩個定義。

請參閱我的singleton article以瞭解實際情況。

1

構造函數應該是私有

4

代碼張貼不作爲一個單獨的工作,由於公共構造,但除此之外,還有許多的缺陷和問題的代碼:

  • 公共構造函數調用實例,該實例調用實例,調用實例,調用.....堆棧溢出迫在眉睫
  • 公用構造函數每次調用都會返回一個新對象,不能用相同的返回結果替換對後續請求提供對象引用。換句話說,單身公共構造函數打破了這種模式。
  • 你不應該泄漏你的鎖對象,在你的情況下,你鎖定對象的類型。不要這樣做,而是鎖定一個私人對象。

這是你的代碼的固定版本:

public class MySingletonClass 
{ 
    private readonly object _mySingletonLock = new object(); 
    private volatile MySingletonClass _mySingletonObj; 

    private MySingletonClass() 
    { 
    // normal initialization, do not call Instance() 
    } 

    public static MySingletonClass Instance() 
    { 
    if (_mySingletonObj == null) 
    { 
     lock (_mySingletonLock) 
     { 
     if (_mySingletonObj == null) 
      _mySingletonObj = new MySingletonClass(); 
     } 
    } 
    return _mySingletonObj; 
    } 
} 

MySingletonClass _myObj = MySingletonClass.Instance(); 
+0

這仍然不是線程安全的 - _mySingletonObj需要是易變的。 – 2009-09-16 11:16:17

+0

注意到,會編輯答案。 – 2009-09-16 11:41:37

1

而不是鎖定它,你也可以嘗試創建一個靜態只讀singelton ...

public sealed class Singleton 
{ 
    private static readonly Singleton instance = new Singleton(); 

    static Singleton() 
    { 
    } 

    private Singleton() 
    { 
    } 

    /// <summary> 
    /// The public Instance property to use 
    /// </summary> 
    public static Singleton Instance 
    { 
     get { return instance; } 
    } 
} 
3

檢查出來的。 NET優化代碼部分Dofactory。這有IMO最好的實施。還請查看該網站以獲取C#中的其他設計模式實現。

+0

Dofactory的+1。偉大的網站學習模式。 – Rap 2009-09-16 11:59:34

0

單例的本質是提供:

  • 正好跨系統類的一個實例;
  • 簡單的訪問它。

Singleton的實現基於使用方法(或.NET中的屬性)創建一個類,該方法創建此類的實例(如果尚不存在)。類的構造函數必須是私有的,以防止其他方式的初始化。 Singleton也必須小心使用在多線程應用程序中,因爲在一個時間點,這兩個線程可能會創建兩個不同的實例(這違反了單例模式)。

更多細節和例子,你可以找到here.

相關問題