23種設計模式->單例模式
1.單例模式保證了整個程序中該物件只被例項化一次,該物件常駐記憶體
2.單例模式的三種寫法
2.1 第一種方法: 雙if加lock鎖
//類
public class SingleLu
{ //第一步建立私有建構函式
private SingleLu()
{
Console.WriteLine("{0}被構造,執行緒id={1}", this.GetType().Name, Thread.CurrentThread.ManagedThreadId);
}
//第二部 建立私有靜態變數
private static SingleLu _Singleton = null;
private static object Singleton_Lock = new object();
public static SingleLu CreateInstance()
{
if (_SingleLu == null)//保證執行緒,不需要等待鎖
{
Console.WriteLine("readyGo");
lock (SingleLu_Lock)//確保只有一個執行緒進入
{
if (_SingleLu == null)//確保物件為空
{
_SingleLu = new SingleLu();
}
}
}
return _SingleLu;
}
public void ComeOn()
{
Console.WriteLine("這裡呼叫了{0}.Show,執行緒id={1}", this.GetType().Name, Thread.CurrentThread.ManagedThreadId);
}
}
//非同步多執行緒呼叫
List<IAsyncResult> asyncList = new List<IAsyncResult>();
for (int i = 0; i < 10; i++)
{
asyncList.Add( new Action(() =>
{
SingleLu singlelu = SingleLu.CreateInstance();
singlelu.ComeOn();
}).BeginInvoke(null, null));
}
控制檯返回結果:
readyGo
readyGo
SingleLu被構造,執行緒id=7
readyGo
這裡呼叫了SingleLu.Show,執行緒id=6
這裡呼叫了SingleLu.Show,執行緒id=5
這裡呼叫了SingleLu.Show,執行緒id=5
這裡呼叫了SingleLu.Show,執行緒id=9
這裡呼叫了SingleLu.Show,執行緒id=4
這裡呼叫了SingleLu.Show,執行緒id=8
這裡呼叫了SingleLu.Show,執行緒id=10
這裡呼叫了SingleLu.Show,執行緒id=3
這裡呼叫了SingleLu.Show,執行緒id=6
這裡呼叫了SingleLu.Show,執行緒id=7
2.2 第二種方法
public class SingleSecond
{
private static SingleSecond _SingleSecond = null;//建立靜態變數
static SingleSecond()//建立靜態建構函式,由CLR保證,在第一次使用這個類之前呼叫而且只調用一次
{
_SingleSecond = new SingleSecond();
}
public static SingleSecond CreateInstance()//建立靜態物件方法
{
return _SingleSecond;
}
public void ComeOnSecond()
{
Console.WriteLine("這裡呼叫了{0}.Show,執行緒id={1}", this.GetType().Name, Thread.CurrentThread.ManagedThreadId);
}
}
//非同步多執行緒呼叫
List<IAsyncResult> asyncList = new List<IAsyncResult>();
for (int i = 0; i < 10; i++)
{
asyncList.Add(new Action(() =>
{
SingleSecond singlelu = SingleSecond.CreateInstance();
singlelu.ComeOnSecond();
}).BeginInvoke(null, null));//會啟動一個非同步多執行緒呼叫
}
返回結果
這裡呼叫了SingleSecond.Show,執行緒id=8
這裡呼叫了SingleSecond.Show,執行緒id=5
這裡呼叫了SingleSecond.Show,執行緒id=5
這裡呼叫了SingleSecond.Show,執行緒id=4
這裡呼叫了SingleSecond.Show,執行緒id=3
這裡呼叫了SingleSecond.Show,執行緒id=9
這裡呼叫了SingleSecond.Show,執行緒id=8
這裡呼叫了SingleSecond.Show,執行緒id=6
這裡呼叫了SingleSecond.Show,執行緒id=7
這裡呼叫了SingleSecond.Show,執行緒id=5
2.3 第三種方法
public class SingleThird
{
private SingleThird()//私有建構函式
{
Console.WriteLine("{0}被構造,執行緒id={1}", this.GetType().Name, Thread.CurrentThread.ManagedThreadId);
}
/// <summary>
/// 靜態變數:會在型別第一次使用的時候初始化,而且只初始化一次
/// </summary>
private static SingleThird _SingleThird = new SingleThird();
public static SingleThird CreateInstance()
{
return _SingleThird;
}
public void ComeOn()
{
Console.WriteLine("這裡呼叫了{0}.ComeOn,執行緒id={1}", this.GetType().Name, Thread.CurrentThread.ManagedThreadId);
}
}
//多執行緒呼叫
List<IAsyncResult> asyncList = new List<IAsyncResult>();
for (int i = 0; i < 10; i++)
{
asyncList.Add(new Action(() =>
{
SingleThird singlelu = SingleThird.CreateInstance();
singlelu.ComeOn();
}).BeginInvoke(null, null));//會啟動一個非同步多執行緒呼叫
}
while (asyncList.Count(r => !r.IsCompleted) > 0)
{
Thread.Sleep(10);
}
返回結果
SingleThird被構造,執行緒id=4
這裡呼叫了SingleThird.ComeOn,執行緒id=4
這裡呼叫了SingleThird.ComeOn,執行緒id=4
這裡呼叫了SingleThird.ComeOn,執行緒id=4
這裡呼叫了SingleThird.ComeOn,執行緒id=10
這裡呼叫了SingleThird.ComeOn,執行緒id=7
這裡呼叫了SingleThird.ComeOn,執行緒id=9
這裡呼叫了SingleThird.ComeOn,執行緒id=5
這裡呼叫了SingleThird.ComeOn,執行緒id=6
這裡呼叫了SingleThird.ComeOn,執行緒id=3
這裡呼叫了SingleThird.ComeOn,執行緒id=8