美文网首页
单利设计模式(二)

单利设计模式(二)

作者: T_log | 来源:发表于2018-06-25 23:26 被阅读13次

单利模式的问题

其实在之前就写了一篇关于单利设计模式中的懒汉式,也解决了懒汉式中存在的多线程安全问题,但是深入理解的时候,才发现问题很多

  1. 饿汉式的情况是怎么样的
  2. 在实现单利后,且保证线程安全的创建对象,序列化问题有考虑吗?
  3. 下面就开始吧

先来一段饿汉式创建对象的方式

 * @author : jzb219@gmail.com
 * @description : 单利设计模式
 * @date : 2018/6/25
 */
public class Singleton {

    //1、在类内部实例化一个对象
    private static Singleton singleton = new Singleton();

    //2、构造器时有,防止外部进行new对象
    private Singleton(){}

    //3、对外提供一个获取实例的静态方法
    public static Singleton getInstance(){
        return singleton;
    }

     public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2);
    }
}

来看一下结果
说明:
在类加载的时候,通过Static静态初始化的方式,就可以在类加载的时候创建对象
由于一个类只有一个类加载器,且是在静态初始化的时候创建,所以可以实现线程安全

 true

而懒汉式的方式,虽然使用DCL+volatile的方式,但是在反序列一个已经序列化过的对象的时候,就很难保证对象的唯一了

  1. 如果只是implements serializable是不行的,真心不明到底什么意思,为什么不行呢,真心很难明白,又仔细看了一下序列化的实现,JDK源码中的ObjectStreamClass的getSerialFields方法
  2. 该方法在序列化类对象的时候getDefaultSerialFields用反射的方式来序列化
  3. 每次在反序列化的时候都会创建一个新的实例,由于反序列化使用的是反射技术,所以相当于对象创建的时候就是创建一个新的对象
  4. 如何解决呢?
/**
     * Returns ObjectStreamField array describing the serializable fields of
     * the given class.  Serializable fields backed by an actual field of the
     * class are represented by ObjectStreamFields with corresponding non-null
     * Field objects.  Throws InvalidClassException if the (explicitly
     * declared) serializable fields are invalid.
     */
    private static ObjectStreamField[] getSerialFields(Class<?> cl)
        throws InvalidClassException
    {
        ObjectStreamField[] fields;
        if (Serializable.class.isAssignableFrom(cl) &&
            !Externalizable.class.isAssignableFrom(cl) &&
            !Proxy.isProxyClass(cl) &&
            !cl.isInterface())
        {
            if ((fields = getDeclaredSerialFields(cl)) == null) {
                fields = getDefaultSerialFields(cl);
            }
            Arrays.sort(fields);
        } else {
            fields = NO_FIELDS;
        }
        return fields;
    }

看下解决

使用final防止序列化
参考(http://www.hollischuang.com/archives/1373)

1. 很累了,准备洗澡休息了
2. 稳住情绪,坚定方向,一定能赢

相关文章

  • JavaJavascript基础进阶(十七)JS中常用的设计模式

    单利设计模式、构造原型设计模式、发布订阅设计模式、promise设计模式 单利模式 构造原型设计模式 最贴近OOP...

  • 单利设计模式(二)

    单利模式的问题 其实在之前就写了一篇关于单利设计模式中的懒汉式,也解决了懒汉式中存在的多线程安全问题,但是深入理解...

  • 细品 javascript 设计模式(单利模式)

    我尽量用最少的文字,最少的篇幅,讲明白设计模式的方方面面。文章连接 理解单利模式 上代码:通用的惰性单利模式 单利...

  • 单利设计模式

    单利模式的介绍 单利模式是应用最广的模式之一,也可能是很多初级工程师唯一会使用的设计模式。在应用这个模式时,单利对...

  • 2018-05-14

    单利设计模式 懒汉式 单例模式 饿汉式 单利模式 懒汉式与饿汉式的区别: 双重锁式 单例模式 (DCL )

  • 设计模式---单利

    public class Text02 {public static void main(String[] arg...

  • iOS 面试高频知识点

    一, 设计模式 mvc、mvvm 、单利、工厂、责任链等应用场景 二, KVO KVC 三,算法(快排重点) 四,...

  • 单利模式设计详解

    @interfaceSingleton:NSObject + (Singleton *)sharedSinglet...

  • JavaScript - 设计模式 - 命名空间

    本小节主要讲解三种常用的设计模式和命名空间,第一种是工厂模式,第二种是单利模式,第三种是观察者模式 设计模式概述 ...

  • 一次支付的终值和现值

    一 单利模式下的终值和现值 单利终值:​​F=P*(1+i*n) 单利现值:P=F/(1+i*n) 二 复利模...

网友评论

      本文标题:单利设计模式(二)

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