class STWindow
{
static Window win;
private STWindow() { }
public static Window GetInstance()
{
if (win == null || !win.IsVisible)
{
win = new Window();
win.Height = 200;
win.Width = 200;
}
return win;
}
}
class Singleton
{
static Singleton _singleton;
private Singleton() { }
public static Singleton GetInstance()
{
if (_singleton == null)
{
_singleton = new Singleton();
}
return _singleton;
}
}
1. 多執行緒同時創建實體問題
多個執行緒同時訪問 Singleton 的 GetInstance() 方法,可能會造成創建多個實體;
比如 A 先進入后在準備實體化 Singleton 的程序中,B 也進入了,這時 _singleton 還是為 null,然后 B 也去實體化 Singleton 了,
class Singleton
{
static Singleton _singleton;
private Singleton() { }
public static Singleton GetInstance()
{
if (_singleton == null)
{
Console.WriteLine("實體化一個 Singleton");
_singleton = new Singleton();
}
Console.WriteLine("回傳一個 Singleton");
return _singleton;
}
}
System.Threading.Thread a = new System.Threading.Thread(() =>
{
Singleton.GetInstance();
});
System.Threading.Thread b = new System.Threading.Thread(() =>
{
Singleton.GetInstance();
});
System.Threading.Thread c = new System.Threading.Thread(() =>
{
Singleton.GetInstance();
});
a.Start();
b.Start();
c.Start();
實體化一個 Singleton
實體化一個 Singleton
回傳一個 Singleton
回傳一個 Singleton
回傳一個 Singleton
我們通過加個鎖來解決這個問題,
public static readonly object syncRoot = new object();
public static Singleton GetInstance()
{
lock (syncRoot)
{
if (_singleton == null)
{
Console.WriteLine("實體化一個 Singleton");
_singleton = new Singleton();
}
}
Console.WriteLine("回傳一個 Singleton");
return _singleton;
}
實體化一個 Singleton
回傳一個 Singleton
回傳一個 Singleton
執行緒 0x1a08 已退出,回傳值為 0 (0x0),
回傳一個 Singleton
執行緒 0x45b4 已退出,回傳值為 0 (0x0),
執行緒 0x5a04 已退出,回傳值為 0 (0x0),
2. 每次實體都要鎖的性能問題
使用雙重鎖定,只有未實體化時才鎖,鎖完判斷是否還未實體化,
public static Singleton GetInstance()
{
if (_singleton == null)
{
lock (syncRoot)
{
if (_singleton == null)
{
_singleton = new Singleton();
}
}
}
return _singleton;
}
3.餓漢式單例
class Singleton
{
static readonly Singleton _instance = new Singleton();
private Singleton() { }
public static Singleton GetInstance()
{
return _instance;
}
}
這種靜態初始化的方式是自己被加載時就將自己實體化,因此被稱為餓漢式單例;
而第一次被參考時才將自己實體化的方式被稱為懶漢式單例,C# 中餓漢式已足夠滿足,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/241174.html
標籤:.NET技术
上一篇:設計模式 - 17)組合模式
