Java多线程系列-多线程下的Singleton模式

Singleton是老生常谈的一个设计模式,不过在之前学习的时候,我并没有将多线程的问题考量在内,所以在这篇里面加入多线程,细细聊来。

首先,就写出一个最简单的singleton,在单线程模式下,该实现没有任何问题,这是真正安全的模式:

?
1
2
3
4
5
6
7
8
9
10
11
public class SingletonClass {
     
     private static SingletonClass singletonClass = new SingletonClass();
     
     private SingletonClass(){}
     
     public static SingletonClass getInstance(){
         return singletonClass;
     }
 
}

例子中,SingletonClass的对象是在初始化时进行了实例化,然后每次调用getInstance方法都返回同一个实例。我们还可以采用Lazy Initialization的方式。即初始化时设置singletonClass=null,在getInstance时再进行实例化操作。

当我们考虑到多线程的问题,要使用双检锁来避免并发导致的判断条件失效,使用synchronized关键字来保证实例化操作的原子性,最后必须要提到的是volatile关键字,使用此关键字是为了确保共享变量的可见性,在一些情况下变量的值不会被立刻更新到物理内存,而是在缓存中,volatile使得变量值的变化需要直接更新到物理内存,使多个线程可以同步知晓该变化。但是该方法仍然不能够保证在所有的JVM上都正确实现了volatile,仍然是有风险的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class SingletonClass {
      # 如果没有 volatile则更加不安全
     private static volatile SingletonClass singletonClass = null ;
     
     public static SingletonClass getInstance(){
         
         if (singletonClass == null ){
             synchronized (SingletonClass. class ) {
                 if (singletonClass == null ){
                     singletonClass = new SingletonClass();
                 }
             }
         }
         return singletonClass;
     }
}

你可能感兴趣的:(JAVA,Java多并高)