设计模式 -- 单例模式 设计模式 - 单例模式

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

设计模式 - 单例模式

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
csharp复制代码class Singleton{
   private static Singletion instance;
   
   //采用 private,防止实例化多个对象
   private Singleton(){
  }
   
   //为外界提供访问接口
   public static Singletion GetInstance(){
       if(instance == null){
           instance = new Singleton();
      }
       return instance;
  }
}

但是在多线程中会出现同时访问 GetInstance() 方法的情况,仍然会 new 出多个 Singleton() 实例,这时候我还想使用单例模式要怎么办呢?

这时想到可以使用锁来规避这种情况.这里只列出了 synchronized 这种方法,当然你也可以使用 Lock 或者 Volatile来实现相同的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
csharp复制代码class Singleton{
   private static Singletion instance;
   private Obgect lock = new Obgect();
   
   //采用 private,防止实例化多个对象
   private Singleton(){
  }
   
   //为外界提供访问接口
   public static Singletion GetInstance(){
       synchronized(lock){
           if(instance == null){
               instance = new Singleton();
          }
           return instance;
      }
  }
}

这种方法创建的Singleton() 实例是由第一次进入的线程进行创建的,所以之后的线程进入之后,并不需要在创建新的实例,从而在多线程中同时访问也不会创建出新的实例.

可是你一定觉得这样每次调用 GetInstance() 都会访问锁,使得多线程变成了单线程,影响性能。所以接下来看看下面的方法,只是做了一个小小的改动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
csharp复制代码class Singleton{
   private static Singletion instance;
   
   //采用 private,防止实例化多个对象
   private Singleton(){
  }
   
   //为外界提供访问接口
   public static Singletion GetInstance(){
       if(instance == null){
           synchronized(lock){
               if(instance == null){
                   instance = new Singleton();
              }
          }
      }
       return instance;
  }
}

这样只有没有创建实例的时候进行加锁处理,有实例则会直接返回,不需要每次都对它进行加锁处理。不仅保证了仅仅创建一次实例,并且同时还保证里多线程的性能。当然了这么神奇又好用的方法也应该有一个自己的名字吧,它叫 Double-Check Locking(双重锁定),

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%