面试官让我谈谈懒汉和饿汉,我一下子说出了六种单例模式的实现方式!

2021-08-24  本文已影响0人  攻城狮Chova

单例模式

单例模式的实现方式

  • 静态类Static :
    • 静态类在第一次运行时直接初始化,也不需要在延迟加载中使用
    • 在不需要维持任何状态,仅仅用于全局访问时,使用静态类的方式更加方便
    • 如果需要被继承或者需要维持一些特定状态下的情况,就适合使用单例模式

线程不安全懒汉

线程安全懒汉

双检锁

饿汉

静态内部类

枚举

  • 懒汉式和饿汉式实现的单例模式破坏 : 无论是通过懒汉式还是饿汉式实现的单例模式,都可能通过反射和反序列化破坏掉单例的特性,可以创建多个对象
  • 反射破坏单例模式: 利用反射,可以强制访问单例类的私有构造器,创建新的对象
public static void main(String[] args) {
  // 利用反射获取单例类的构造器
  Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
  // 设置访问私有构造器
  constructor.setAccessiable(true);
  // 利用反射创建新的对象
  Singleton newInstance = constructor.newInstance();
  // 通过单例模式创建单例对象
  Singleton singletonInstance = Singleton.getInstance();
  // 此时这两个对象是两个不同的对象,返回false
  System.out.println(singletonInstance  == newInstance);
}
  • 反序列化破坏单例模式: 通过readObject() 方法读取对象时会返回一个新的对象实例
public static void main(String[] args) {
  // 创建一个输出流对象
  ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("Singleton.file"));
  // 将单例类对象写入到文件中
  Singleton singletonInstance = Singleton.getInstance();
  os.writeObject(singleton);
  // 从文件中读取单例对象
  File file = new File("Singleton.file");
  ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
  Singleton newInstance = (Singleton)is.readObject();
  // 此时这两个对象是两个不同的对象,返回false
  System.out.println(singletonInstance == newInstance);
}
上一篇 下一篇

猜你喜欢

热点阅读