欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#设计模式 —— 单例模式

程序员文章站 2023-01-29 13:11:12
嗯,这是本人的第一篇随笔,就从最简单的单例模式开始,一步一步地记录自己的成长。 单例模式是最常见的设计模式之一,在项目代码中几乎随处可见。这个设计模式的目的就是为了保证实例只能存在一个。单例模式往下还能再细分为懒汉模式和饿汉模式。下面逐个来看。 1.饿汉模式 饿汉模式的做法是在类加载的时候就完成实例 ......

  嗯,这是本人的第一篇随笔,就从最简单的单例模式开始,一步一步地记录自己的成长。

  单例模式是最常见的设计模式之一,在项目代码中几乎随处可见。这个设计模式的目的就是为了保证实例只能存在一个。单例模式往下还能再细分为懒汉模式和饿汉模式。下面逐个来看。

1.饿汉模式

  饿汉模式的做法是在类加载的时候就完成实例化,是线程安全的做法。

 1     public class singleton
 2     {
 3         //类加载的时候完成实例化
 4         private static singleton instance = new singleton();
 5 
 6         private singleton()
 7         {
 8         }
 9 
10         //直接返回实例
11         public static singleton instance
12         {
13             get
14             {
15                 return instance;
16             }
17         }
18     }

 

2.懒汉模式

  懒汉模式的做法就是在类加载的时候不创建实例,在第一次使用的时候才创建。但是这种做法并不是线程安全的,如果多个线程同时调用instance,便会有多个实例创建,这就违反了单例模式的初衷。

 1     public class singleton
 2     {
 3         // 类加载的时候不直接创建实例
 4         private static singleton instance;
 5 
 6         private singleton()
 7         {
 8 
 9         }
10 
11         public static singleton instance
12         {
13             get
14             {
15                 if (instance == null)
16                 {
17                     //第一次使用的时候创建实例
18                     instance = new singleton();
19                 }
20 
21                 return instance;
22             }
23         }
24     }

3.线程安全懒汉模式

  如何保证线程安全的同时又实现懒汉模式?最简单的方式就是在if判断外上锁。

 1     public class singleton
 2     {
 3         private static singleton instance;
 4 
 5         private static readonly object locker = new object();
 6 
 7         private singleton()
 8         {
 9 
10         }
11 
12         public static singleton instance
13         {
14             get
15             {
16                 //上锁
17                 lock (locker)
18                 {
19                     if (instance == null)
20                     {
21                         instance = new singleton();
22                     }
23                 }
24 
25                 return instance;
26             }
27         }
28     }

  但是这种做法在每次访问前的需要上锁,会影响多线程的性能,于是我们又有了双重检验锁。

4.双重检验锁

  我们只需要在上锁之前再作一次if判断,就不会每次访问的时候都需要上锁了。

 1     public class singleton
 2     {
 3         private static singleton instance;
 4 
 5         private static readonly object locker = new object();
 6 
 7         private singleton()
 8         {
 9 
10         }
11 
12         public static singleton instance
13         {
14             get
15             {
16                 if (instance == null)
17                 {
18                     lock (locker)
19                     {
20                         if (instance == null)
21                         {
22                             instance = new singleton();
23                         }
24                     }
25                 }
26 
27                 return instance;
28             }
29         }
30     }