设计模式之单例模式

本文详细介绍了单例模式的实现方式,包括最简单的实现、惰性实例化和类型构造器方法,并通过代码示例展示了如何在多线程环境下确保类只有一个实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:
保证一个类仅有一个实例,并提供一个访问它的全局访问点

实现方式:

1.最简单的方式

  public  class Singleton
    {
         private  static Singleton _instance;
         private Singleton()
        {
            Console.WriteLine( " 我被实例化了 ");
        }
         public  static Singleton Instance
        {
             get
            {  
                return _instance == null ? (new Singleton()) : _instance;
            }
        }       
    }

 上面代码保证3点:第一,类不能被实例化(私有构造函数);第二,类不能被继承(私有构造函数);第三,提供一个全局访问的静态属性。

保证以上3点,单线程里我们就可以确保一个类只能提供一个实例,但是多线程下就不能确保了,我们看一下代码:

 

ExpandedBlockStart.gif 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();
        }

 我们新开了3个线程(包含主线程共4个线程),发现单例居然被实例化了4次,也就是说:每个线程独立实例化了Singleton,这可违背单例模式的初衷

 

2.惰性实例化

 为了解决线程的安全问题,我们可以在单例中加一个锁,保证同一时刻只能有一个线程访问,一旦存在实例,将不再实例化单例类,重新设计单例类代码如下:

 

ExpandedBlockStart.gif 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;

            }

        }
}

 这样运行代码后发现无论启动多少个线程,都能保证类只有一个实例

 3.类型构造器方法(或者称为静态构造器法)

这种做法的优点是:让线程的安全性交给CLR来负责,这也是.NET中推荐的一种单例设计方式,代码如下:

 

ExpandedBlockStart.gif 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;

            }
        }     
    }

总之,以上就我在项目中经常使用的方式,当然还有其他更多的实现方式,你可以参看园子中其他大牛的文章,比如TerryLee的设计模式系列:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值