这种方式仍然存在并发的同步阻塞问题,并且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关键字保证了多线程环境下变量的可见性,避免了指令重排序,从而保证了单例的正确创建。 此外,单例模式还有几种变体,比如...
下面将详细介绍七种常见的单例模式实现方式,并结合多线程环境和反序列化测试进行讨论。 1. **饿汉式单例**: 这是最简单的单例实现,它在类加载时就创建了实例,因此是线程安全的。 ```java public class ...
同时,枚举避免了序列化导致的多实例问题。 以上就是关于单例模式的一些核心概念和常见实现方式。在实际开发中,根据需求和场景选择合适的实现方式至关重要,以平衡性能和资源使用。同时,需要注意的是,过度依赖...
特别是在现代软件开发中,考虑到多线程环境、类加载机制以及序列化等因素的影响,合理地设计和实现单例模式变得尤为重要。通过上述讨论,我们可以看到单例模式在不同场景下的适用性及其潜在问题,并学习到了相应的...
然而,如果涉及类加载器或跨JVM的场景,单例模式的实现就需要更复杂的策略,例如使用`序列化`和`克隆`时需要特殊处理,防止生成额外的实例。另外,如果要考虑服务集群或分布式系统,可能需要采用分布式单例,例如...
本文将详细讨论四种常见的单例实现方式:饿汉模式、懒汉模式、双重检查锁定(DCL)单例模式以及枚举单例。 1. **饿汉模式**: 饿汉模式是在类加载时就完成了实例化,避免了线程同步问题。这种方式简单且安全,但...
在实际应用中,还可以考虑使用枚举(Enum)方式来实现单例,它既简单又线程安全,同时避免了序列化问题。例如: ```java public enum Singleton { INSTANCE; public void studentManagement() { // 实现学生...
然而,序列化和反序列化可能会破坏单例模式,因为每次反序列化都会创建一个新的实例。为了防止这种情况,我们需要在Singleton类中实现`readResolve()`方法: ```java import java.io.ObjectStreamException; ...
单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种...在理解了各种实现方式后,才能更好地利用单例模式解决实际问题。
下面我们将详细介绍六种常见的单例模式,并探讨在Android环境下如何应对反序列化安全问题。 1. 饿汉式单例(Static Singleton) 这是最简单的单例实现方式,通过静态常量来存储唯一实例,保证在类加载时就完成初始...
4. 防止序列化和反序列化:如果允许对象被序列化和反序列化,可能会导致单例模式失效,因此我们需要封锁`__wakeup()`和`__sleep()`方法。 ```php class Singleton { // ... private function __wakeup() { ...
单例模式是软件设计模式中的一种,它的主要...在实际应用中,还需要考虑JVM的垃圾回收机制、序列化以及测试等方面的问题,以确保单例模式的正确性和健壮性。理解并熟练运用单例模式,有助于提高代码的可维护性和效率。
总之,Java中的单例模式虽然简单,但在多线程、类加载器和序列化等特定场景下需要特别注意,以确保其正确性和安全性。开发者应当根据具体的应用场景选择合适的单例实现方式,以达到最佳的效果。
此外,通过使用枚举方式实现单例,可以防止反射和序列化带来的多实例问题。 总结来说,单例模式是一种重要的设计模式,用于控制类实例的数量,以优化资源管理和提高效率。在实际开发中,我们需要根据具体需求选择...
枚举的单例模式简单易懂,且天然线程安全,不会受到反射和序列化攻击的影响,是推荐的单例实现方式之一。 总的来说,单例模式是一种常见的设计模式,懒汉式单例模式则是其中一种实现策略,它的主要特点是延迟加载和...
最安全且最简单的实现方式,防止反射攻击,同时避免了序列化带来的问题。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 以上就是Java中常见的单例模式实现方式,每...
而如果考虑到反射攻击和序列化问题,可能需要选择DCL或枚举实现。在使用单例模式时,还需要注意以下几点: - 单例模式可能导致程序设计过度集中,不利于模块化。 - 序列化时需谨慎处理,否则可能会生成多个实例。 - ...
这是Joshua Bloch在《Effective Java》中推荐的方式,既简单又线程安全,无需担心序列化问题。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 以上就是Java中实现单例模式...