用全局变量使得一个对象被访问,但是它不能防止你实例化多个对象。最好的办法是,让类自身负责保存它唯一的实。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法
class Singleton
{
private static Singleton instance;
private Singleton()
{ }
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
Console.WriteLine("一样哒~~");
Console.Read();
}
}
讲真,我看到这段精妙的代码都惊呆了 Σ( ° △ °|||)︴ GetInstance()
是静态方法 保证了不用实例化就能调用。居然类里面还能保存自己实例化的对象!!
但是出现的隐患是多线程创建多个实例
lock可以确保一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待
class Singleton
{
private static Singleton instance;
private static readonly object support = new object();
private Singleton()
{ }
public static Singleton GetInstance()
{
if (instance == null)
{
lock(support)
{
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
Console.WriteLine("一样哒~~");
Console.Read();
}
}
注意一下为什么要判断两次,有两个线程调用这个方法的时候,都可以通过第一个==null的判断,由于lock机制,这两个线程只有一个进入,另一个等着,如果没有第二个判断,第二个进程还是可以再创造新的实例
C#也提供了静态初始化的方法,这种方法不需要开发人员显示的编写线程安全代码,即可以解决多线程环境下它不是安全的问题
sealed 密封类 阻止发生派生 也就阻止增加实例
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton()
{ }
public static Singleton GetInstance()
{
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
Console.WriteLine("一样哒~~");
Console.Read();
}
}
昨天晚上和对象说单例模式,说起来既然是static静态类型的对象为什么不能一开始就实例化一个?反正static是全局的,只会最多有一个对象,但是如果一开始就生成对象,如果构造函数执行时间很长会造成不必要的开销。但是readonly导致必须一开始就声明