美文网首页
单例模式

单例模式

作者: afree_ | 来源:发表于2018-02-03 19:45 被阅读0次

    定义

    一个类只有一个实例,该实例必须自行创建,并且向整个系统提供这个实例

    实现考虑因素

    • 唯一性
      • 是否防克隆
      • 是否防反射
      • 是否防序列化
    • 性能
      • 是否需要懒加载
      • 是否防指令重排(双重锁方式问题)

    三种实现方式

    实现 懒加载 线程安全 防克隆 防反射 防序列化
    双重锁
    静态内部类
    枚举

    双重锁方式(添加了防御功能)

    public class Singleton implements Serializable, Cloneable {
    
        private static volatile Singleton sSingleton; // volatile防止指令重排
        private static boolean sFlag = true;
        private Singleton() {
            if(sFlag){ // 防反射
                sFlag = false;
            }else{
                throw new RuntimeException("对象已经存在");
            }
        }
    
        public static Singleton getSingleton() {
            if (sSingleton == null) {
                synchronized (Singleton.class) {
                    if (sSingleton == null) {
                        sSingleton = new Singleton();
                    }
                }
            }
            return sSingleton;
        }
    
        private Object readResolve() {
            return getSingleton(); // 防序列化
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return getSingleton(); // 防克隆
        }
    }
    
    

    静态内部类方式

    public class Instance {
        private Instance() {
        }
    
        private static class Holder {
            // 类加载机制保证懒加载,static&final确保线程安全
            private static final Instance INSTANCE = new Instance();
        }
    
        public static Instance getInstance() {
            return Holder.INSTANCE;
        }
    
    }
    

    枚举类方式

    public enum Single {
        SINGLE;
        public void whateverMethod(){
        }
    }
    

    基本等价于(除enum的防反射、序列化、克隆等属性)

    public final class Single{
        public static final Single SINGLE = new Single();
    }
    

    测试代码

     public static void main(String args[]) {
    
            try {
                Singleton singleton = Singleton.getSingleton();
                testCloneSingleton(singleton);
                testReflectSingleton(singleton);
                testSerializableSingleton(singleton);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static void testCloneSingleton(Singleton singleton) throws CloneNotSupportedException {
    
            boolean equals = singleton.equals(Singleton.getSingleton().clone());
    
            System.out.print(equals);
        }
    
        private static void testReflectSingleton(Singleton singleton) throws Exception {
            Constructor constructor = Singleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            constructor.newInstance();
    
            boolean equals = singleton.equals(constructor.newInstance(););
    
            System.out.print(equals);
    
        }
    
        private static void testSerializableSingleton(Singleton singleton) throws Exception {
            String tempFile = "tempFile";
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tempFile));
            oos.writeObject(getSingleton());
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(tempFile)));
    
            boolean equals = singleton.equals(objectInputStream.readObject());
    
            System.out.print(equals);
    
        }
    

    相关文章

      网友评论

          本文标题:单例模式

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