JavaSE面试题之一:写一个Singleton

JavaSE面试题之一:写一个Singleton

关于Singleton的说明

  • 单例设计模式,即某个类在系统中只能有一个实例对象可被获取和使用的代码模式
  • 例如:代表JVM运行环境的Runtime类

要点

  • 某个类只能有一个实例
    • 构造器私有化
  • 必须自行创建这个实例
    • 含有一个该类的静态变量来保存这个唯一实例
  • 必须自行向整个系统提供这个实例
    • 对外提供获取该实例对象的方式
      • 直接暴露
      • 用静态变量的get方法获取

常见形式

  • 饿汉式:直接创建对象,不存在线程安全问题

    • 直接实例化(简洁直观)
      /**
      * 饿汉式
      *  直接创建对象,不管你是否需要这个对象都会创建
      *  1.私有化构造器
      *  2.自行创建,并用静态变量保存
      *  3.向外提供这个实例(直接声明为public)
      *  4.强调这是一个单例,可以用final关键字修饰
      */
      public class Singleton {
      
          public static final Singleton INSTANCE = new Singleton();
      
          private Singleton() {
      
          }
      }
      
    • 枚举类型(最简洁)
      /**
       * 枚举类型
       *  表示该类型的对象是有限的几个
       *  我们可以限定为1个,就成了单例
       */
      public enum Singleton {
          INSTANCE
      }
      
    • 静态代码块饿汉式(适合复杂实例化)
      public class Singleton {
      
          public static final Singleton INSTANCE;
      
          static {
              INSTANCE = new Singleton();
          }
      
          private Singleton() {
      
          }
      }
      
      下面是其一个实际应用场景
      public class Singleton {
      
          public static final Singleton INSTANCE;
          private String info;
      
          static {
              try {
                  Properties properties = new Properties();
                  // 注意文件必须在src路径下才能加载
                  properties.load(Singleton.class.getClassLoader().getResourceAsStream("singleton.properties"));
                  INSTANCE = new Singleton(properties.getProperty("name"));
              } catch (IOException e) {
                  throw new RuntimeException();
              }
          }
      
          private Singleton(String info) {
              this.info = info;
          }
      }
      
  • 懒汉式:延迟创建对象

    • 线程不安全(适合于单线程)
      /**
       * 懒汉式:延迟创建这个实例对象
       *  1.构造器私有化
       *  2.用一个静态变量保存这个唯一实例
       *  3.提供一个静态方法,获取这个实例对象
       *  ! 以下代码线程不安全
       */
      public class Singleton {
          private static Singleton INSTANCE;
      
          private Singleton() {
      
          }
      
          public static Singleton getInstance() {
              if (INSTANCE == null) {
                  INSTANCE = new Singleton();
              }
              return INSTANCE;
          }
      
      }
      
    • 线程安全(适用于多线程)
      public class Singleton {
         private static Singleton INSTANCE;
      
         private Singleton() {
      
         }
      
         public static Singleton getInstance() {
             if (INSTANCE == null) { // 提升性能
                 synchronized (Singleton.class) {
                     if (INSTANCE == null) {
                         INSTANCE = new Singleton();
                     }
                 }
             }
             return INSTANCE;
         }
      
      }
      
    • 静态内部类形式(适用于多线程)
      /**
        * 在内部类被加载和初始化时,才创建INSTANCE
        * 静态内部类不会随着外部类的加载和初始化而初始化,它是要单独加载和初始化的
        * 该方法线程安全
        */
       public class Singleton {
      
           private Singleton() {
      
           }
      
           private static class Inner {
               private static final Singleton INSTANCE = new Singleton();
           }
      
           public static Singleton getInstance() {
               return Inner.INSTANCE;
           }
      
       }
      

小结

  • 如果是饿汉式,那么枚举类方式最简洁

  • 如果是懒汉式,静态内部类形式最简洁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水能zai舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值