Java 单例模式

线程安全的单例模式的几种实现方法分享
线程安全的单例模式实现有几种思路,个人认为第2种方案最优雅

  • 饿汉式
  • 借助内部类
  • 普通加锁解决
  • 双重检测
    但要注意写法,如果单体模式继续扩展为N元单体模式,那就是对象池模式了

1、饿汉式单例

public class Singleton {
   private final static Singleton INSTANCE = new Singleton();
   private Singleton() { }
   public static Singleton getInstance() {
      return INSTANCE;
   }
}

2、借助内部类,相对来说,这个比较省事,不过也因为是内部类,当前对象的持有也需要注意。

public class Singleton {
   private Singleton() {}
   private static class SingletonHolder {
      private final static Singleton INSTANCE = new Singleton();
   }
   public static Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
}

3、懒汉模式下的几种情况

  • 3.1 普通加锁模式,虽然解决了线程安全问题,但是每个线程调用getInstance都要加锁
public class Singleton {
   private static Singleton instance = null;
   private Singleton() {}
   public static synchronized Singleton getInstance() {
      if(instance == null) {
         instance = new Singleton();
      }
      return instance;
   }
}
  • 3.2 双重检测,但要注意写法,由于指令重排序问题的问题,所以这种写法比较安全可靠一些
public class Singleton {
   private static Singleton instance = null;
   private Singleton() { }
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            Singleton temp = instance;
            if(temp == null) {
               temp = new Singleton();
               instance = temp
            }
         }
      }
      return instance;
   }
}
  • 3.3 双重检测,使用volatile修饰,这样的话就可以确保instance = new Singleton(); 对应的指令不会重排序
public class Singleton {
   private static volatile Singleton instance = null;
   private Singleton() {}
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            if(instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
}

3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行

public class Singleton {
   private static Singleton instance = null;
   private Singleton() { }
   public static Singleton getInstance() {
      if(instance == null) {
         synchronzied(Singleton.class) {
            if(instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 实现单例模式 饿汉模式和懒汉模式单例模式根据实例化时机分为饿汉模式和懒汉模式。饿汉模式,是指不等到单例真正使...
    aaron1993阅读 231评论 0 0
  • java 单例模式指整个程序中只有一个某个类的实例,通常被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件...
    dcme阅读 1,065评论 0 10
  • 第一种(懒汉式,线程不安全):public class Singleton {private static Sin...
    yljava阅读 4,059评论 0 0
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,780评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,026评论 19 139