`
shifulong
  • 浏览: 59177 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

单例模式以及序列化仍然单例的问题

    博客分类:
  • java
阅读更多

 

这种方式仍然存在并发的同步阻塞问题,并且jdk1.5之前是有问题的

public class SeriSingleDCL {

    // volatile 多线程并发的可见性
    private volatile static SeriSingleDCL single = null;

    private SeriSingleDCL() {
    }

    /**
     * DCL方式减少同步的阻塞
     */
    public static SeriSingleDCL getInstance() {
        if (single == null) {
            synchronized (SeriSingleDCL.class) {
                if (single == null) {
                    single = new SeriSingleDCL();
                    return single;
                }
            }
        }
        return single;
    }
}

 

 

于是就有了静态内部类的方式&序列化单例问题解决(readResolve方法重写)

public class SeriSingle implements Serializable {

    private static SeriSingle seriSingle;

    /**
     * 被调用的时候才会被加载,实现延迟初始化
     */
    private static class SeriSingleHolder {
        // static jvm保证初始化的多线程可见性
        private static SeriSingle instance = new SeriSingle();
    }

    public static SeriSingle getInstance() {
        return SeriSingleHolder.instance;
    }

    /**
     * 反序列化会调用这个方法,从而保证单例模式的单例性
     * 否则反序列化的时候会生成另一个对象
     */
    private Object readResolve() {
        return SeriSingle.getInstance();
    }
}

class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("/Users/***/test/seritest.obj");

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(SeriSingle.getInstance());
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        SeriSingle readObject = (SeriSingle) ois.readObject();
        ois.close();

        //如果没有实现SeriSingle#readResolve()方法,这将使两个对象
        System.out.println(readObject == SeriSingle.getInstance());
    }
}

  

 

分享到:
评论

相关推荐

    设计模式之单例模式(结合工厂模式)

    DCL模式通过在实例化单例时使用 volatile 关键字和双层检查,解决了这个问题。volatile关键字保证了多线程环境下变量的可见性,避免了指令重排序,从而保证了单例的正确创建。 此外,单例模式还有几种变体,比如...

    7种单例模式

    下面将详细介绍七种常见的单例模式实现方式,并结合多线程环境和反序列化测试进行讨论。 1. **饿汉式单例**: 这是最简单的单例实现,它在类加载时就创建了实例,因此是线程安全的。 ```java public class ...

    设计模式——单例模式

    同时,枚举避免了序列化导致的多实例问题。 以上就是关于单例模式的一些核心概念和常见实现方式。在实际开发中,根据需求和场景选择合适的实现方式至关重要,以平衡性能和资源使用。同时,需要注意的是,过度依赖...

    单例模式,single

    特别是在现代软件开发中,考虑到多线程环境、类加载机制以及序列化等因素的影响,合理地设计和实现单例模式变得尤为重要。通过上述讨论,我们可以看到单例模式在不同场景下的适用性及其潜在问题,并学习到了相应的...

    单例模式详解~~单例模式详解~~

    然而,如果涉及类加载器或跨JVM的场景,单例模式的实现就需要更复杂的策略,例如使用`序列化`和`克隆`时需要特殊处理,防止生成额外的实例。另外,如果要考虑服务集群或分布式系统,可能需要采用分布式单例,例如...

    单例模式(饿汉模式、懒汉模式、DCL单例模式、枚举)

    本文将详细讨论四种常见的单例实现方式:饿汉模式、懒汉模式、双重检查锁定(DCL)单例模式以及枚举单例。 1. **饿汉模式**: 饿汉模式是在类加载时就完成了实例化,避免了线程同步问题。这种方式简单且安全,但...

    使用单例模式创建学生管理系统(饿汉式、懒汉式)

    在实际应用中,还可以考虑使用枚举(Enum)方式来实现单例,它既简单又线程安全,同时避免了序列化问题。例如: ```java public enum Singleton { INSTANCE; public void studentManagement() { // 实现学生...

    Java单例模式设计

    然而,序列化和反序列化可能会破坏单例模式,因为每次反序列化都会创建一个新的实例。为了防止这种情况,我们需要在Singleton类中实现`readResolve()`方法: ```java import java.io.ObjectStreamException; ...

    单例模式各种实现方式

    单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种...在理解了各种实现方式后,才能更好地利用单例模式解决实际问题。

    单例模式介绍

    下面我们将详细介绍六种常见的单例模式,并探讨在Android环境下如何应对反序列化安全问题。 1. 饿汉式单例(Static Singleton) 这是最简单的单例实现方式,通过静态常量来存储唯一实例,保证在类加载时就完成初始...

    php单例模式实例

    4. 防止序列化和反序列化:如果允许对象被序列化和反序列化,可能会导致单例模式失效,因此我们需要封锁`__wakeup()`和`__sleep()`方法。 ```php class Singleton { // ... private function __wakeup() { ...

    五种单例模式

    单例模式是软件设计模式中的一种,它的主要...在实际应用中,还需要考虑JVM的垃圾回收机制、序列化以及测试等方面的问题,以确保单例模式的正确性和健壮性。理解并熟练运用单例模式,有助于提高代码的可维护性和效率。

    单例模式(singleton)

    此外,通过使用枚举方式实现单例,可以防止反射和序列化带来的多实例问题。 总结来说,单例模式是一种重要的设计模式,用于控制类实例的数量,以优化资源管理和提高效率。在实际开发中,我们需要根据具体需求选择...

    设计模式——单例模式(懒汉模式)

    枚举的单例模式简单易懂,且天然线程安全,不会受到反射和序列化攻击的影响,是推荐的单例实现方式之一。 总的来说,单例模式是一种常见的设计模式,懒汉式单例模式则是其中一种实现策略,它的主要特点是延迟加载和...

    设计模式-单例模式

    最安全且最简单的实现方式,防止反射攻击,同时避免了序列化带来的问题。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 以上就是Java中常见的单例模式实现方式,每...

    Java单例模式深入理解

    而如果考虑到反射攻击和序列化问题,可能需要选择DCL或枚举实现。在使用单例模式时,还需要注意以下几点: - 单例模式可能导致程序设计过度集中,不利于模块化。 - 序列化时需谨慎处理,否则可能会生成多个实例。 - ...

    单例模式源代码

    这是Joshua Bloch在《Effective Java》中推荐的方式,既简单又线程安全,无需担心序列化问题。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 以上就是Java中实现单例模式...

Global site tag (gtag.js) - Google Analytics