设计模式课程 设计模式精讲 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
[email protected]67aece
[email protected]67aece
true

Process finished with exit code 0

原文地址:https://www.cnblogs.com/1446358788-qq/p/11374488.html

时间: 2024-10-04 16:15:20

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

JAVA_SE基础——37.单例设计模式

本文继续介绍23种设计模式系列之单例模式. 我们在javaSE的基础学习中,会讲到:单例设计模式.模板设计模式.装饰者设计模式.观察者设计模式.工厂设计模式 我以后随着水平的提高,我会专门开个分类写设计模式的.现在请原谅我的知识面有限-- 设计模式→中的    "模式" 二字是什么意思.. 模式:模式就是解决 一类 问题的固定步骤 . 模式的概念最早起源于建筑行业.... 建房子的步骤都是一样子: 打地基-----> 浇柱子------->盖楼面--------->砌

IOS开发之单例设计模式

本文将从四个方面对IOS开发中的单例设计模式进行讲解: 一.什么是单例设计模式 二.我们为什么要用单例设计模式 三.单例设计模式的基本用法 四.自定义单例设计模式代码的封装 一.什么是单例设计模式 所谓单例,即是单个的实例化对象,保证一个类有且仅有一个实例.通常情况下,当我们对一个类实例化时(如:alloc.new等),并不能保证每次实例化的对象是唯一的实例.那么为了保证该类可在多次实例化的过程中保证内存地址不变,就需要引入单例设计模式. 二.我们为什么要用单例设计模式 1.Singleton

iOS核心笔记——多线程-单例设计模式

1.单例设计模式: 2.单例设计模式实现(ARC模式): 2-1.单例设计模式步骤: ?重要:①提供一个静态全局变量:②重写allocWithZone方法,使用一次性方法保证只分配一次存储空间.③提供快速创建单例对象的类方法:④严谨起见,还应重写copyWithZone.mutableCopyWithZone方法. 2-2.确保内存分配: 2-3.提供类方法: 3.单例模式三个问题: ?重要:①:怎么实现一个单例模式?(重写allocWithZone方法)②:内部是怎么确保只分配一次内存?(在a

Java设计模式—单例设计模式(Singleton Pattern)全然解析

转载请注明出处:http://blog.csdn.net/dmk877/article/details/50311791 相信大家都知道设计模式,听的最多的也应该是单例设计模式,这种模式也是在开发中用的最多的设计模式,可能有非常多人会写几种设计模式.那么你是否知道什么是设计模式?为什么会有单例设计模式即它的作用是什么?单例模式有哪些写法?对于这种问题.可能有部分童鞋并不能非常好的回答,没关系今天就和大家一起来具体的学习下单例设计模式,相信通过学习本篇你将对单例设计模式有个具体的理解. 如有谬误欢

单例设计模式【掌握】

概念 什么是设计模式? ? 设计模式是别人已经总结好的可以解决问题的方案 ? 设计模式23种,常用的是单例设计模式,工厂设计模式,生产者消费者设计模式,代理委托设计模式等 什么是单例设计模式? ? 单例:单个的实例,单个的对象 ? 程序在运行的过程中,确保某一个类只能有一个实例[对象],不管在程序的哪个位置获取,获取到的都是同一个对象 单例设计模式的核心;一个类有且只能有一个对象,并且该对象可以应用于整个程序中 使用 1.使用new 类似于构造函数,优先于构造函数 代码演示: #__new__:

设计模式总纲——单例设计模式

前两天写了设计模式总纲,今天就来讲讲我们在工程代码中最最最常用的设计模式了——单例设计模式,这个模式在工程代码上的出现率几乎为99.99999%,但是虽然很常用,但是用的好的人却不多,今天我们就来深入的说一说单例设计模式. 在学习一项新的知识之前,我们都要向自己提出三个问题,为什么要用这个知识,这个知识用在哪里,这个知识怎么用?既 why,where,how,3W模式,我们先来谈谈为什么需要单例设计模式,先来想想,如果一个工具类,比如一个读取配置文件的工具类,这类工具只是特定的功能类,既读取指定

iOS开发之单例设计模式(完整正确版本)

单例的意思从字面上就可以略知一二,所谓单例就是确保在程序运行过程中只创建一个对象实例.可以用于需要被多次广泛或者说多次使用的资源中,比如我们常见的网络请求类.工具类以及其它管理类等.比如我iOS开发中常见的系统单例[UIApplication sharedApplication].[NSUserDefaults  standardUserDefaults]等.在iOS开发中,单例模式是非常有用的一种设计模式.如下图,是一个简单的例模式的UML类图. 一.使用单例模式的作用 它可以保证某个类在程序

JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是class对象 我们在上节验证了同步函数的锁是this,但是对于静态同步函数,你又知道多少呢? 我们做一个这样的小实验,我们给show方法加上static关键字去修饰 private static synchronized void show() { if (tick > 0) { try { Thread

JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖

JAVA之旅(六)--单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 java也越来越深入了,大家加油吧!咱们一步步来 一.单例设计模式 什么是设计模式? JAVA当中有23种设计模式,解决某一问题最有效的方法 单例设计模式 解决一个类在内存中只存在一个对象 想要保证对象唯一该怎么做> 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象 2.还为了让其他程序访问到该类对象,只好在本类中自定义一个对象 3.为了方便其他程序对自定义对象的访问,可以对外提供