• 单例模式


    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,反序列化后两个实例是同一个。

  • 相关阅读:
    枚举和字符串转换
    JavaScript string.format
    Jquery 中toggle的用法举例
    JQuery 实现倒计时
    找位置
    图算法
    文件操作总结
    动态规划——总结
    回文字符串
    a+b_1
  • 原文地址:https://www.cnblogs.com/cici20166/p/5554750.html
Copyright © 2020-2023  润新知