设计模式课程 设计模式精讲 8-6 单例设计模式-序列化破坏单例模式原理解析及解决方案

1    原理解析

2    代码演练

2.1  原理解析

2.2  解决方案

1    原理解析

2    代码演练

2.1  原理解析

测试类:

package com.geely.design.pattern.creational.singleton;

import java.io.*;

public class Test {

    /*public static void main(String [] args){
        //这样写异常,因为构造方法私有
//        LazySingleton lazySingleton = new LazySingleton();
       LazySingleton lazySingleton = LazySingleton.getInstance();
       System.out.println(lazySingleton);
    }*/

/*    public static void main(String [] args){
        Thread thread1 = new Thread(new T());
        Thread thread2 = new Thread(new T());
        thread1.start();
        thread2.start();
        System.out.println("结束了!!!");
    }*/

    /**
     * 序列化代码演练
     * 将 HungrySingleton对象放入文件,再从文件读取该对象,还是同一个对象吗?
     * 实际应用:在从文件存入后读取,用equals时需要注意(equals比较的是hash码)
     * @param args
     */
    public static void main(String [] args){
        try {
            //将singleton对象写入到输出流中
            HangrySingleton instance = HangrySingleton.getInstance();
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
            oos.writeObject(instance);

            //从输入流中读取到该对象
            File file = new File("singleton_file");
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
            HangrySingleton instance2 = (HangrySingleton) ois.readObject();
            System.out.println(instance);
            System.out.println(instance2);
            System.out.println(instance==instance2);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

实体类:

package com.geely.design.pattern.creational.singleton;



public class HangrySingleton{


    /**
     * 声明私有常量,当类初始化的时候就已经赋值了。饿汉式在类初始化的时候只加载一次。
     * 所以也不会存在多线程的问题。
     */
    private final static HangrySingleton hangrySingleton;

    static {
        hangrySingleton= new HangrySingleton();
    }

    /**
     * 声明私有构造方法
     */
    private HangrySingleton(){

    }

   

    /**
     * 提供对外接口,获得对象
     * @return
     */
    public static HangrySingleton getInstance(){
        return hangrySingleton;
    }
}

打印日志:

"C:\Program Files\Java\jdk1.7.0_79\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=22216:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_79\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\design_pattern\target\classes" com.geely.design.pattern.creational.singleton.Test
java.io.NotSerializableException: com.geely.design.pattern.creational.singleton.HangrySingleton
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at com.geely.design.pattern.creational.singleton.Test.main(Test.java:33)

Process finished with exit code 0

2.2  解决方案

测试类:

package com.geely.design.pattern.creational.singleton;

import java.io.*;

public class Test {

    /*public static void main(String [] args){
        //这样写异常,因为构造方法私有
//        LazySingleton lazySingleton = new LazySingleton();
       LazySingleton lazySingleton = LazySingleton.getInstance();
       System.out.println(lazySingleton);
    }*/

/*    public static void main(String [] args){
        Thread thread1 = new Thread(new T());
        Thread thread2 = new Thread(new T());
        thread1.start();
        thread2.start();
        System.out.println("结束了!!!");
    }*/

    /**
     * 序列化代码演练
     * 将 HungrySingleton对象放入文件,再从文件读取该对象,还是同一个对象吗?
     * 实际应用:在从文件存入后读取,用equals时需要注意(equals比较的是hash码)
     * @param args
     */
    public static void main(String [] args){
        try {
            //将singleton对象写入到输出流中
            HangrySingleton instance = HangrySingleton.getInstance();
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
            oos.writeObject(instance);

            //从输入流中读取到该对象
            File file = new File("singleton_file");
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
            HangrySingleton instance2 = (HangrySingleton) ois.readObject();
            System.out.println(instance);
            System.out.println(instance2);
            System.out.println(instance==instance2);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

实体类:

package com.geely.design.pattern.creational.singleton;

import java.io.Serializable;

public class HangrySingleton implements Serializable {


    /**
     * 声明私有常量,当类初始化的时候就已经赋值了。饿汉式在类初始化的时候只加载一次。
     * 所以也不会存在多线程的问题。
     */
    private final static HangrySingleton hangrySingleton;

    static {
        hangrySingleton= new HangrySingleton();
    }

    /**
     * 声明私有构造方法
     */
    private HangrySingleton(){

    }

    /**
     *
     */
    private Object readResolve(){
        return hangrySingleton;
    }

    /**
     * 提供对外接口,获得对象
     * @return
     */
    public static HangrySingleton getInstance(){
        return hangrySingleton;
    }
}

打印日志:

"C:\Program Files\Java\jdk1.7.0_79\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=22084:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_79\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\design_pattern\target\classes" com.geely.design.pattern.creational.singleton.Test
com.geely.design.pattern.creational.singleton.HangrySingleton@5c67aece
com.geely.design.pattern.creational.singleton.HangrySingleton@5c67aece
true

Process finished with exit code 0

猜你喜欢

转载自www.cnblogs.com/1446358788-qq/p/11374488.html