1. 单例模式安全问题

    • 序列化和反射问题:

      public class HungrySingleton implements Serializable,Cloneable{
      
          private final static HungrySingleton hungrySingleton;
      
          static{
              hungrySingleton = new HungrySingleton();
          }
          private HungrySingleton(){ //反射时处理,如果已存在则抛出异常
              if(hungrySingleton != null){
                  throw new RuntimeException("单例构造器禁止反射调用");
              }
          }
          public static HungrySingleton getInstance(){
              return hungrySingleton;
          }
      
          private Object readResolve(){//反序列化时会调用此方法,从而防止创建多个实例
              return hungrySingleton;
          }
      
          @Override
          protected Object clone() throws CloneNotSupportedException {
              return getInstance();
          }
      } 
    • 内部类处理方式相同

      public class StaticInnerClassSingleton {
          private static class InnerClass{
              private static StaticInnerClassSingleton staticInnerClassSingleton 
                  = new StaticInnerClassSingleton();
          }
          public static StaticInnerClassSingleton getInstance(){
              return InnerClass.staticInnerClassSingleton;
          }
          private StaticInnerClassSingleton(){
              if(InnerClass.staticInnerClassSingleton != null){
                  throw new RuntimeException("单例构造器禁止反射调用");
              }
          }
      }
  2. Effective java 推荐的枚举类型单例

    public class EnumSingleton {
        //私有构造函数
        private EnumSingleton(){}
    
        public static EnumSingleton getInstance(){
            return Singleton.INSTANCE.getInstance();
        }
    
        private enum Singleton{
            INSTANCE;
            private EnumSingleton singleton;
            //jvm保证这个方法绝对只调用一次
            Singleton(){
                singleton = new EnumSingleton();
            }
            public EnumSingleton getInstance(){
                return singleton;
            }
        }
    }