1. 程式人生 > 其它 >23種設計模式->單例模式

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