保證一個(gè)類僅有一個(gè)實(shí)例诊赊,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)厚满。
在計(jì)算機(jī)系統(tǒng)中,線程池碧磅、緩存碘箍、日志對(duì)象、對(duì)話框鲸郊、打印機(jī)丰榴、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例。
image.png
public class SingletonTest
{
public static void Test()
{
var tasks = new List<Task>();
for (int i = 0; i < 20; i++)
{
tasks.Add(new Task(() =>
{
Singleton singleton = Singleton.Instance();
singleton.GetData();
}));
}
//并發(fā)執(zhí)行20個(gè)任務(wù)
tasks.AsParallel().ForAll(p => p.Start());
}
private class Singleton
{
/// <summary>
/// 靜態(tài)實(shí)例秆撮,利用靜態(tài)字段把實(shí)例緩存起來(lái)
/// </summary>
private static Singleton singleton;
/// <summary>
/// 返回對(duì)象的唯一實(shí)例
/// </summary>
/// <returns></returns>
public static Singleton Instance()
{
if (singleton == null)
{
Console.WriteLine("實(shí)例化對(duì)象");
singleton = new Singleton();
}
return singleton;
}
public void GetData()
{
Console.WriteLine("調(diào)用了getdata()");
}
}
}
看下執(zhí)行結(jié)果
image.png
實(shí)例化對(duì)象動(dòng)作執(zhí)行了4次四濒,說(shuō)明并發(fā)情況下有問(wèn)題;
改下實(shí)現(xiàn)方式,增加鎖
public static Singleton Instance()
{
if (singleton == null)
{
lock (lockObj)
{
Console.WriteLine("實(shí)例化對(duì)象");
singleton = new Singleton();
}
}
return singleton;
}
看下執(zhí)行結(jié)果
image.png
依然不能保證
加鎖并雙重驗(yàn)證
public static Singleton Instance()
{
if (singleton == null)
{
lock (lockObj)
{
if (singleton == null)
{
Console.WriteLine("實(shí)例化對(duì)象");
singleton = new Singleton();
}
}
}
return singleton;
}
看下執(zhí)行結(jié)果
image.png
這下就不會(huì)有并發(fā)的問(wèn)題了