玩转Java设计模式之单例模式一

玩转Java设计模式之单例模式一

编码文章call10242025-06-24 12:15:282A+A-

什么是单例模式

单例模式简单来说,就是要保证一个类在进程内有且只有一个实例对象。这个类对外提供了唯一获取其实例对象的静态方法,且构造方法私有化。


单例模式实现方式

  • 懒汉式(4种)
  • 饿汉式(2种)
  • 静态内部类(1种)
  • 枚举(1种)

懒汉式实现方式一

缺点:并发场景时,线程不安全。

结论:不推荐使用

 public class SingletonDemo3 {
     //直接初始化对象
     private static SingletonDemo3 instance;
     //构造方法私有化
     private SingletonDemo3(){}
     //
     public static SingletonDemo3 getInstance( ){
         if(instance==null){
             instance = new SingletonDemo3();
         }
         return instance;
     }
 }

懒汉式实现方式二

针对实现方式一来进行升级,加入线程同步锁synchronized,保证线程安全。

缺点:由于synchronized加在了方法上,并发场景下都要获取锁,性能较差。

结论:不推荐使用。

 public class SingletonDemo4 {
     //直接初始化对象
     private static SingletonDemo4 instance;
     //构造方法私有化
     private SingletonDemo4(){}
     //
     public static synchronized SingletonDemo4 getInstance( ){
         if(instance==null){
             instance = new SingletonDemo4();
         }
         return instance;
     }
 
 }

懒汉式实现方式三(双重检查+同步锁)

针对实现方式二进行升级,将synchronized放在方法代码块中,保证并发性能。

这种实现方式就完美了吗?NO!!!

缺点:由于java 虚拟机会对class进行指令重排序(JVM在保证最终结果正确的情况下,

可以不按照程序编码的顺序执行语句,尽可能提高程序的性能),在JVM中初始化对象分为三步:

1.为初始化对象分配内存空间;

2.初始化实例对象;

3.将初始化对象指定分配好的内存空间。

在发生指令重排序后,执行顺序为:1->3->2 。并发场景下,可能线程1创建单例时执行了1->3,线程2发现单例已创建,其实得到的是未初始化完成的对象,导致NPE异常。

结论:不推荐使用

 public class SingletonDemo5 {
     //直接初始化对象
     private static SingletonDemo5 instance;
     //构造方法私有化
     private SingletonDemo5(){}
     //
     public static SingletonDemo5 getInstance( ){
         if(instance==null){
             synchronized (SingletonDemo5.class){
                 instance = new SingletonDemo5();
             }
         }
         return instance;
     }
 }

懒汉式实现方式四(双重检查+同步锁+volatile)

针对实现方式三存在的问题进行升级,在单例对象变量前加入volatile关键字修饰,防止指令重排序。

结论:推荐使用。

 public class SingletonDemo6 {
     //直接初始化对象
     private static volatile SingletonDemo6 instance;
     //构造方法私有化
     private SingletonDemo6(){}
     //
     public static SingletonDemo6 getInstance( ){
         if(instance==null){
             synchronized (SingletonDemo6.class){
                 if(instance == null){
                     instance = new SingletonDemo6();
                 }
             }
         }
         return instance;
     }
 }

由于考虑篇幅较长,本章节仅分享懒汉式的4种实现方式,并分析其优缺点,最后给出推荐使用的懒汉式实现方式。下一章节将分享单例模式的饿汉式、静态内部类、枚举实现方式。

如本文使你受益,请给予点赞、关注、收藏、转发,鼓励小编继续创作。

如有错误或不妥之处,欢迎拍砖!!!

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4