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

posted @ 2022-05-08 13:13  LaineyLu  阅读(20)  评论(0)    收藏  举报