• 单例模式


    1.下面这个例子是工作中常见的单例模式...jdk1.5之后用volatile关键字禁止编译器重排序

    package singleton;
    
    public class DoubleCheckSingleton {
        private volatile static DoubleCheckSingleton instance= null;
        private DoubleCheckSingleton(){}
        public static DoubleCheckSingleton getInstance(){
            if(instance == null ) {
                synchronized(DoubleCheckSingleton.class) {
                    if(instance==null) {
                        instance = new DoubleCheckSingleton();
                    }
                }
            }
            return instance;
        }
    }

    2.利用静态内部类生成单例,初始化单例在私有内部静态类中,其他线程无法看到初始化的编译器重排序。

    package singleton;
    
    public class SingletonByHolder{
        private SingletonByHolder(){};
        public static SingletonByHolder getInstance(){
            return SingletonHolder.instance;
        }
        
        private static class SingletonHolder
        {
            private static SingletonByHolder instance = new SingletonByHolder();
        }
    }

    3. 1和2的方法无法防止序列化和反序列化时生成不同的实例,如果单例类需要实现序列化的话,改成下面的方法可以预防(参考《Java程序性能优化》

    package singleton;
    
    import java.io.Serializable;
    
    public class SingletonByHolder implements Serializable{
        private static final long serialVersionUID = 333332L;
        
        private SingletonByHolder(){};
        public static SingletonByHolder instance;
        
        public static SingletonByHolder getInstance(){
            instance = SingletonHolder.instance;
            return instance;
        }
        
        private static class SingletonHolder
        {
            private static SingletonByHolder instance = new SingletonByHolder();
        }
        
        private Object readResolve(){
            return instance;
        }
    }

    测试类

    package singleton;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    public class Test {
        public static void main(String[] args) throws IOException, ClassNotFoundException
        {
            SingletonByHolder instance = SingletonByHolder.getInstance();
            FileOutputStream fo = new FileOutputStream("D:\serSingleton.txt");
            ObjectOutputStream ob = new ObjectOutputStream(fo);
            ob.writeObject(instance);
            ob.flush();
            ob.close();
            fo.close();
            
            FileInputStream fi = new FileInputStream("D:\serSingleton.txt");
            ObjectInputStream oi = new ObjectInputStream(fi);
            SingletonByHolder instance2 = (SingletonByHolder) oi.readObject();
            oi.close();
            fi.close();
            System.out.println(instance == instance2);
        }
    }

    如果注释掉private Object readResolve()方法测试类打印false,反序列化后两个实例不是同一个;没注释掉的话打印true,反序列化后两个实例是同一个。

  • 相关阅读:
    HFish 源码Git下载 源码编译执行
    Windows注册表-学习总结
    利用PHPStudy搭建Xdebug调试环境
    Python3报错Crypto失败(from Crypto.Cipher import AES ModuleNotFoundError: No module named 'Crypto')
    Django后台管理admin字段控制显示长度(字段内容过长,省略号替代)
    PHP代码审计-小题一道
    golang编程-小问题
    迅雷影音播放器-ass字幕乱码-问题
    《独自等待》观影有感
    Python urllib URL 处理模块
  • 原文地址:https://www.cnblogs.com/cici20166/p/5554750.html
Copyright © 2020-2023  润新知