保证一个类仅有一个实例,并提供一个访问它的全局访问点
实现方式:
1.最简单的方式:
public class Singleton
{
private static Singleton _instance;
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
}
}
{
private static Singleton _instance;
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
return _instance == null ? (new Singleton()) : _instance;
}}
}
上面代码保证3点:第一,类不能被实例化(私有构造函数);第二,类不能被继承(私有构造函数);第三,提供一个全局访问的静态属性。
保证以上3点,单线程里我们就可以确保一个类只能提供一个实例,但是多线程下就不能确保了,我们看一下代码:
View Code
class Program
{
static void Main(string[] args)
{
MultWork multThread = new MultWork();
multThread.StartMultThread();
Console.ReadLine();
}
}
public class Singleton
{
private static Singleton _instance;
private static readonly Object padlock = new object();
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
return _instance == null ? (new Singleton()) : _instance;
}
}
}
public class MultWork
{
private static readonly Object padlock = new object();
/// <summary>
/// 线程工作
/// </summary>
public static void DoSomeWork()
{
///构造显示字符串
string results = string.Empty;
///创建一个Sigleton实例
Singleton MyCounter = Singleton.Instance;
///循环调用四次
for (int i = 1; i < 5; i++)
{
results += "线程";
results += Thread.CurrentThread.Name.ToString();
results += "\n";
}
}
public void StartMultThread()
{
Thread thred0 = Thread.CurrentThread;
thred0.Name = "主线线程";
Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
thread1.Name = "thread1";
thread1.Start();
Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
thread2.Name = "thread2";
thread2.Start();
Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
thread3.Name = "thread3";
thread3.Start();
DoSomeWork();
}
{
static void Main(string[] args)
{
MultWork multThread = new MultWork();
multThread.StartMultThread();
Console.ReadLine();
}
}
public class Singleton
{
private static Singleton _instance;
private static readonly Object padlock = new object();
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
return _instance == null ? (new Singleton()) : _instance;
}
}
}
public class MultWork
{
private static readonly Object padlock = new object();
/// <summary>
/// 线程工作
/// </summary>
public static void DoSomeWork()
{
///构造显示字符串
string results = string.Empty;
///创建一个Sigleton实例
Singleton MyCounter = Singleton.Instance;
///循环调用四次
for (int i = 1; i < 5; i++)
{
results += "线程";
results += Thread.CurrentThread.Name.ToString();
results += "\n";
}
}
public void StartMultThread()
{
Thread thred0 = Thread.CurrentThread;
thred0.Name = "主线线程";
Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
thread1.Name = "thread1";
thread1.Start();
Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
thread2.Name = "thread2";
thread2.Start();
Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
thread3.Name = "thread3";
thread3.Start();
DoSomeWork();
}
我们新开了3个线程(包含主线程共4个线程),发现单例居然被实例化了4次,也就是说:每个线程独立实例化了Singleton,这可违背单例模式的初衷
2.惰性实例化
为了解决线程的安全问题,我们可以在单例中加一个锁,保证同一时刻只能有一个线程访问,一旦存在实例,将不再实例化单例类,重新设计单例类代码如下:
View Code
public class Singleton
{
private static Singleton _instance;
private static readonly Object padlock = new object();
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
lock (padlock)
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
{
private static Singleton _instance;
private static readonly Object padlock = new object();
private Singleton()
{
Console.WriteLine("我被实例化了");
}
public static Singleton Instance
{
get
{
lock (padlock)
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
这样运行代码后发现无论启动多少个线程,都能保证类只有一个实例
3.类型构造器方法(或者称为静态构造器法)
这种做法的优点是:让线程的安全性交给CLR来负责,这也是.NET中推荐的一种单例设计方式,代码如下:
View Code
public class Singleton
{
private static Singleton _instance =null;
static Singleton()
{
Console.WriteLine("我被实例化了");
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
{
private static Singleton _instance =null;
static Singleton()
{
Console.WriteLine("我被实例化了");
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
总之,以上就我在项目中经常使用的方式,当然还有其他更多的实现方式,你可以参看园子中其他大牛的文章,比如TerryLee的设计模式系列:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html