美文网首页
完美的单例

完美的单例

作者: 0x5947 | 来源:发表于2018-01-10 16:59 被阅读24次

一、常见的单例实现方式

方式一(静态常量)

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

方式二(内部类)

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

方式三(懒加载)

public final class Singleton implements Serializable {
  private static final Singleton INSTANCE;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(INSTANCE == null){
      synchronized(Singleton.class){
        if(INSTANCE == null){
          INSTANCE = new Singleton();
        }
      }
    }
    return INSTANCE;
  }
}

二、常见单例实现方式的问题

  1. 方式一的问题在于类加载时候即加载实例。
  2. 方式二看起来好像没什么问题,在使用的时候才会加载内部类。
  3. 方式三需要线程同步开销,效率不高。

除了以上提到的问题,他们在序列化的情况下会存在一个通用的问题;如果你使用RMI发送这个单例对象,你会得到一个新的实例。

如果要解决这个问题,你需要在类中添加一个readResolve()方法,这样在反序列化的时候可以直接返回已有的实例用以替换序列化的数据,代码就像下面这样:

 public final class Singleton implements Serializable {
    //省略其它代码......
    ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
 }

三、完美的单例实现

  1. 方式一

     public final class PerfectSingleton implements Serializable {
       public static class Inner{
         private static final PerfectSingleton INSTANCE = new PerfectSingleton();
       }
       private PerfectSingleton(){
         if(Inner.INSTANCE != null){
           throw new Error("denied access.");
         }
       }
       public static PerfectSingleton getInstance(){
         return Inner.INSTANCE;
       }
       private Object readResolve() throws ObjectStreamException{
         return Inner.INSTANCE;
       }
     }
    
  2. 方式二

     public enum Singleton{
         INSTANCE;
     }
    

总结:方式一可以很好的实现懒加载问题,线程安全问题,反序列化问题,防反射攻击,但是比较繁琐;如果图省事建议直接使用枚举实现,安全又便捷

相关文章

  • 你真的会写单例吗?

    你真的会写单例吗? 摘录来源 单例的正确姿势 Java单例模式可能是最简单也是最常用的设计模式,一个完美的单例需要...

  • 完美的单例

    一、常见的单例实现方式 方式一(静态常量) 方式二(内部类) 方式三(懒加载) 二、常见单例实现方式的问题 方式一...

  • 老司机来教你单例的正确姿势

    老司机来教你单例的正确姿势 Java单例模式可能是最简单也是最常用的设计模式,一个完美的单例需要做到哪些事呢? 单...

  • iOS开发之单例模式

    一. 单例模式简介:首先我们应该明白,我们每个项目中AppDelegate就是一个完美的单例.(1)在程序运行过程...

  • C++简洁完美的单例模式实现

    完美的单例模式是线程安全的,使用懒汉模式。Lock类用于加锁解锁,Singleton类为单例类。不过还可能出现问题...

  • iOS 单例中dispatch_once的原理

    先来段代码: 这是利用dispatch_once实现单例的方式,运行看看会输出什么: 生成完单例对象后,在其他地方...

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • 2020-11-02-Spring单例 vs. 单例模式

    Spring 单例不是 Java 单例。本文讨论 Spring 的单例与单例模式的区别。 前言 单例是 Sprin...

网友评论

      本文标题:完美的单例

      本文链接:https://www.haomeiwen.com/subject/svvonxtx.html