• 欢迎访问我爱CSharp学习网,这里有最新最全的C#书籍,C#视频。
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏我爱C#学习网吧
  • 推荐使用最新版Chrome浏览器和火狐浏览器访问本网站

C# 设计模式之单例模式

C#杂烩 52csharp 1411次浏览 0个评论 扫描二维码

C# 设计模式之单例模式

单例模式:一个类在内存中只有一个对象(实例),并且提供一个可以全局访问或者获取这个对象的方法。

这两天学的,写了个小例子,问了同事一些关于线程的问题,还有从网上查了一些资料。还犯了一些低级的错误。

vs2017控制台输出文字乱码,从网上找了一些方法不管用,最后发现是自己新建项目选错模板了,选择了.NET CORE的模板,所以才会输出乱码,大家一定要吸取教训。

直接上代码

演示类,Person.cs

C# 设计模式之单例模式

    public class Person
 {    /// <summary>
       /// 实例化一个私有静态变量,存储类本身的实例    
       /// </summary>
       private static Person _person  = null;    
       /// <summary>
       /// 构造函数    
       /// </summary>
       private Person()
   {
     Console.WriteLine("构造了一个{0}",GetType().Name);
   }
          public static Person GetInstance()
   {      if(_person == null)
       _person = new Person();      return _person;
   }  
 }

C# 设计模式之单例模式

客户端代码:

{ 

var person1 = Person.GetInstance();
var person2 = Person.GetInstance();
var person3 = Person.GetInstance();
Console.WriteLine("person1 == person2:{0}", object.ReferenceEquals(person1, person2)); }

输出结果:

C# 设计模式之单例模式

只输出了一次,两个对象引用相等。说明单例模式没问题。

 

 进阶:

C# 设计模式之单例模式

 public class Person
{    /// <summary>
       /// 实例化一个私有静态变量,存储类本身的实例    
       /// </summary>
       private static Person _person  = null;    
       /// <summary>
       /// 构造函数    
       /// </summary>
       private Person()
   {
     Console.WriteLine("构造了一个{0}",GetType().Name);
   }    public static Person GetInstance()
   {      if (_person == null)
       _person = new Person();      return _person;
   }
}

C# 设计模式之单例模式

客户端调用代码:

C# 设计模式之单例模式

      {
       Person person1 = null;
       Person person2 = null;
       Person person3 = null;        
       //多线程下可以输出多次
               
               var thread1 = new Thread(() => { person1 = Person.GetInstance(); });        
               var thread2 = new Thread(() => { person2 = Person.GetInstance(); });        
               var thread3 = new Thread(() => { person3 = Person.GetInstance(); });
       thread1.Start();
       thread2.Start();
       thread3.Start();
       Thread.Sleep(1000);//等待子线程完成
               Console.WriteLine("person1 == person2:{0}", object.ReferenceEquals(person1, person2));
     }

C# 设计模式之单例模式

输出结果:

C# 设计模式之单例模式

输出了多次,引用也不相等。说明多次实例化这个类,单例模式写的不完全正确,那让我们加上线程安全验证。

 

继续进阶: 

C# 设计模式之单例模式

 public class Person
{    /// <summary>
       /// 实例化一个私有静态变量,存储类本身的实例    
       /// </summary>
       private static Person _person  = null;    
       /// <summary>
       /// 作为锁的对象,使用私有的、静态的并且是只读的对象    
       /// </summary>
       private static readonly object _obj = new object();    
       /// <summary>
       /// 构造函数    
       /// </summary>
       private Person()
   {
     Console.WriteLine("构造了一个{0}",GetType().Name);
   }    
       /// <summary>
       /// 获取类唯一的实例对象    
       /// </summary>
       public static Person GetInstance()
   {      
       if (_person == null)//先判断是否为空      
   {        l
       ock (_obj)//再判断下是否有别的线程在使用        
       {          
       if (_person == null)
       //等其他线程使用完成后再判断是否为空          
       {
           _person = new Person();
         }
       }
     }      return _person;
   }
}

C# 设计模式之单例模式

客户端调用代码:

C# 设计模式之单例模式

      {        
     //使用锁,锁住的对象:使用私有的、静态的并且是只读的对象
               Person person1 = null;
       Person person2 = null;
       Person person3 = null;        
       //多线程下可以输出多次
               var thread1 = new Thread(() => { person1 = Person.GetInstance(); });        
               var thread2 = new Thread(() => { person2 = Person.GetInstance(); });        
               var thread3 = new Thread(() => { person3 = Person.GetInstance(); });
       thread1.Start();
       thread2.Start();
       thread3.Start();
       Thread.Sleep(1000);//等待子线程完成
               Console.WriteLine("person1 == person2:{0}", object.ReferenceEquals(person1, person2));
     }

C# 设计模式之单例模式

输出结果:

C# 设计模式之单例模式

输出一次,引用相等,说明单例模式成功,线程安全已经加上。

进阶2

可以使用静态构造函数作为单例模式:

C# 设计模式之单例模式

    public class Person
 {    /// <summary>
       /// 实例化一个私有静态变量,存储类本身的实例    
       /// </summary>
       private static Person _person  = null;    
       /// <summary>
       /// 构造函数    
       /// </summary>
       private Person()
   {
     Console.WriteLine("构造了一个{0}",GetType().Name);
   }    
       /// <summary>
       /// 静态构造函数,只执行一次    
       /// </summary>
       static Person()
   {
     _person = new Person();
   }    
       /// <summary>
       /// 获取类的实例    
       /// </summary>
       public static Person GetInstance()
   {      return _person;
   }
 }

C# 设计模式之单例模式

客户端代码:

C# 设计模式之单例模式

     {        
    //使用锁,锁住的对象:使用私有的、静态的并且是只读的对象        
    //使用静态构造函数,在里面初始化person对象
               Person person1 = null;
       Person person2 = null;
       Person person3 = null;        
       //多线程下可以输出多次
               var thread1 = new Thread(() => { person1 = Person.GetInstance(); });        
               var thread2 = new Thread(() => { person2 = Person.GetInstance(); });        
               var thread3 = new Thread(() => { person3 = Person.GetInstance(); });
       thread1.Start();
       thread2.Start();
       thread3.Start();
       Thread.Sleep(1000);//等待子线程完成
               Console.WriteLine("person1 == person2:{0}", object.ReferenceEquals(person1, person2));
     }

C# 设计模式之单例模式

 输出一次,引用相等,静态构造函数也可以作为单例模式实现的一种方法。




C# 设计模式之单例模式



我爱CSharp学习网 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C# 设计模式之单例模式
喜欢 (1)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址