单例模式 Singleton Pattern

单例模式的要点:
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。
 
从具体实现角度来说,就是以下三点:
一是单例模式的类只提供私有的构造函数;
二是类定义中含有一个该类的静态私有对象;
三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
 
懒汉模式(被调用时创建 ,线程不安全)
 1 /// <summary>
 2     /// lazy singleton pattern( 线程不安全实例可能被创建多次 已优化)
 3     /// </summary>
 4     class Singleton
 5     {
 6         private static Singleton _instance=null;
 7 
 8         private static object _lock = new object();
 9 
10         private Singleton()
11         {
12             Console.WriteLine("被创建");
13         }
14 
15         public static Singleton GetInstance()
16         {
17             Console.WriteLine("加载中");
18 
19             if (_instance==null)//双重加锁  解决线程并发安全的问题
20             {
21                 lock (_lock)
22                 {
23                     if (_instance == null)
24                     {
25                         return _instance = new Singleton();
26                     }
27                 }
28 
29             }
30            
31             return _instance;
32         }

 调用

static void Main(string[] args)
        {
            HashSet<string> vs = new HashSet<string>();
            Console.WriteLine("lazy");
            TaskFactory taskFactory = new TaskFactory();
            List<Task> tasks = new List<Task>();
            Thread.Sleep(5000);
            for (int i = 0; i < 5; i++)
            {
                tasks.Add(taskFactory.StartNew(() =>
                {
                    Singleton temp = Singleton.GetInstance();
                    vs.Add(temp.ToString());
                }));

            }
            Thread.Sleep(5000);
            Console.WriteLine(vs.Count);
            Console.Read();
        }

优化前 实例被创建多次

 

 

 优化后

 

 

饿汉模式

 1     /// <summary>
 2     /// EagerPattern 先创建实例  线程安全 耗内存 效率变低
 3     /// </summary>
 4     class EagerSingleton
 5     {
 6         private readonly static EagerSingleton _instance = new EagerSingleton();
 7         private EagerSingleton()
 8         {
 9         }
10         public EagerSingleton GetInstance()
11         {
12            return _instance;
13         }
14     }

在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。这个类被加载时,会自动实例化这个类。但是不管用不用,都会先实例化。

 

 

posted @ 2019-12-10 18:40  是不是唐辛子啊  阅读(351)  评论(0编辑  收藏  举报