首页
学习
活动
专区
圈层
工具
发布

java设计模式之单例模式|单例模式之饿汉模式、懒汉模式、枚举方式|最详细的6种懒汉模式详解

,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?...如果是后者,则在 3 执行完毕、2 未执行之前,另外一个线程B抢夺到了CPU的执行权,这时instance已经是非null了(但却没有初始化),所以线程B会直接返回 instance,然后使用,结果就会出现问题了...ObjectInputStream 会检查对象的class是否定义了readResolve方法。如果定义了,将由readResolve方法指定返回的对象。...()方法注释执行一下和不注释执行一下,分别查看一下打印结果 注释readResolve()方法执行结果,返回的是内存地址不同  不注释readResolve()方法执行结果,返回的内存地址相同  这就是为什么我将单例模式都要加一个...能解决系统的97%了 我这里额外加了一个懒汉模式6静态内部类防止反射,并且讲述了必须加一个readResolve()方法,不然会有序列化问题。

2K40
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    设计模式之单例模式

    在程序需要用到的时候再创建实例,这样保证了内存不会被浪费。针对懒汉模式,这里给出了5种实现方式,有些实现方式是线程不安全的,也就是说在多线程并发的环境下可能出现资源同步问题。...不都是一样的,说明在多线程环境下,产生了多个对象,不符合单例模式的要求。...和饿汉模式一样,是靠JVM保证类的静态成员只能被加载一次的特点,这样就从JVM层面保证了只会有一个实例对象。那么问题来了,这种方式和饿汉模式又有什么区别呢?不也是立即加载么?...()方法到底是何方神圣,其实当JVM从内存中反序列化地”组装”一个新对象时,就会自动调用这个 readResolve方法来返回我们指定好的对象了, 单例规则也就得到了保证。...readResolve()的出现允许程序员自行控制通过反序列化得到的对象。

    57430

    Java单例模式的写法及优缺点

    最重要的是,当创建好实例对象之后,就不必继续进行同步了。...DCL虽然在一定程度解决了资源的消耗和多余的同步,线程安全等问题,但是他还是在某些情况会出现失效的问题,**也就是DCL失效,在《Java并发编程实践》一书建议用静态内部类单例模式来替代DCL。...问题出现的顺序: 1, 线程A, 发现对象未实例化, 准备开始实例化 2, 由于编译器优化了程序指令, 允许对象在构造函数未调用完前, 将共享变量的引用指向部分构造的对象, 虽然对象未完全实例化,...虽然在线程A的工作区res和d都是完整的,但有JSL没有强制不允许先把res映射到主存储区,如果哪个jvm实现按它的优化方案先把工作存储器中的res同步到主存储器了,这时正好线程B获取了,而d却没有同步过去...反序列化操作提供了readResolve方法,这个方法可以让开发人员控制对象的反序列化。

    97220

    GPT-5.4初步体验:一个真正面向工作流的大模型出现了

    GPT-5.4初步体验:一个真正面向工作流的大模型出现了凌晨2点的时候,GPT-5.4直接发布。...对于做研究、分析、方案设计、表格建模、长文档归纳的人,这类提升通常是最值钱的。第二,代码和Agent工作流提升较大。...第三,多模态能力带来的惊艳感很强。第四,它适合真实工作流,而不只是考试流。第五,后续模型的变化,未必都符合所有人的审美。...Q7:操作系统的自带的日历日历功能可直接调用系统级接口,操作流程比较顺畅写在最后整体看下来,GPT-5.4最值得关注的,不只是benchmark再次刷新,而是它明显更像一个真正能进入工作流的“干活型”模型了...它的重点转向了更稳定地完成任务:看文档、读表格、调工具、跑网页、写代码、串联多步流程。这背后反映出的,其实是大模型竞争方向的变化——现在不是拼大模型谁更强的时代了,会干活的大模型才能够有更多用户使用。

    30910

    Java单例模式

    在程序需要用到的时候再创建实例,这样保证了内存不会被浪费。针对懒汉模式,这里给出了5种实现方式,有些实现方式是线程不安全的,也就是说在多线程并发的环境下可能出现资源同步问题。...: 需要额外的工作来实现序列化,否则每次反序列化一个序列化的对象时都会创建一个新的实例。...不过,在实际工作中,很少看见有人这么写。 3.7 序列化与反序列化 为什么要提序列化和反序列化呢?因为单例模式虽然能保证线程安全,但在序列化和反序列化的情况下会出现生成多个对象的情况。...//运行结果 865113938 调用了readResolve方法 865113938 其实当JVM从内存中反序列化地"组装"一个新对象时,就会自动调用这个 readResolve方法来返回我们指定好的对象了...readResolve()的出现允许程序员自行控制通过反序列化得到的对象。

    39010

    3分钟快速阅读-《Effective Java》(七)

    简单来说对于异常可能出现的情况进行尽可能的声明,这样让调用你的人才能知道要怎么来使用对应的方法 63.在细节消息中包含能捕获失败的信息 简单来说,对于可能出现业务逻辑异常处应当做好对应的日志记录...,这样才能更好的跟踪有些我们无法预料捕获而是由程序帮我们抛出的异常信息 64.努力使失败保持原子性 总而言之,当异常出现的时候肯定存在某个对象出现了某个问题,那么此时当我们捕获异常的时候需要让这个对象保持它出现异常的状态...开始,Java平台发布了Exceutor Framework,它创建了一个工作队列.只需要一行代码即可实现 //单线程执行器 ExecutorService executorService = Executors.newSingleThreadExecutor...70.1 不可变类.该类的实例是完全不可改变的.类似枚举类 70.2 无条件的线程安全.这个类的实例是可变的,但是访问的方法都是同步方法. 70.3 有条件的线程安全,这个类的实例是可变的,存在不是同步的方法可供外部调用...74.1 实现Serializable接口,一旦这个类被发布了,就降低了改变这个类的实现的灵活性 74.2 增加了出现Bug和安全漏洞的可能性 74.3 增加了测试负担 75.考虑使用自定义序列化 public

    46410

    Java单例---序列化破坏单例模式原理解析

    ,会出现不同的实例,举个例子: import java.io.*; public class Test { public static void main(String[] args) throws...newDoubleLock); System.out.println(doubleLock == newDoubleLock); } } 输出结果:(第一次运行会报错,这里略过不介绍了...所以,我们就会发现序列化之后出现了两个不同的DoubleLock 实例。 那么如何解决这个问题呢?...= null); } 可以看到这是一个反射有关的方法,作用是:如果表示的类是实现了serializable/externalizable的,并定义一个符合的readResolve方法则返回true,否则...那么在反射中调用了我们在单例中定义的“readResolve”方法,这个方法返回了我们已经创建的单例实例,所以读取的类就成了我们在单例中创建的类,而不是上面三目运算创建的新的实例。 好了!

    32320

    当Kotlin邂逅设计模式之单例模式(一)

    二、定义 保证某个类只有一个实例对象,该实例对象在内部进行实例化,并且提供了一个获取该实例对象的全局访问点。...实例,不管有没有使用,只要KSingleton被加载了, //静态代码块就会被调用,KSingleton实例就会被创建,并赋值给INSTANCE KSingleton var0 = new...synchronized同步锁,锁住getInstance方法,每一次调用该方法的时候都得获取锁,但是如果这个单例已经被初始化了,其实按道理就不需要申请同步锁了,直接返回这个单例类实例即可。...= UNINITIALIZED_VALUE//为了解决DCL带来指令重排序导致主存和工作内存数据不一致的问题,这里使用Volatile原语注解。...然而为了让开发者能够控制反序列化,提供一个特殊的钩子方法那就是readResolve方法,这样一来我们只需要在readResolve直接返回原来的实例即可,就不会创建新的对象。

    1.1K30

    Effective-java-读书笔记之序列化

    如果没有显式声明, 系统会自动生成.实现Serializable的第二个代价是, 它增加了出现Bug和安全漏洞的可能性. -> 反序列化是一个隐藏的构造器.实现Serializable的第三个代价是,....第89条 对于实例控制, 枚举类型优先于readResolve如果单例模式的类加上了implements Serializable, 就多了一种创建实例的途径.readResolve特性允许你用readObject...对于一个正在被反序列化的对象, 如果它的类定义了一个readResolve方法, 并且具备正确的声明, 那么在反序列化之后, 新建对象上的readResolve方法就会被调用.....如果依赖readResolve进行实例控制, 带有对象引用类型的所有实例域都必须声明为transient的.从历史上来看, readResolve方法被用于所有可序列化的实例受控(instance-controlled...自从Java1.5以来, 它就不再是在可序列化的类中维持实例控制的最佳方法了.应该尽可能地使用枚举类型来实施实例控制的约束条件.但是如果这不可能做到, 或者你需要一个实现了序列化的实例受控的类, 那么你就必须提供一个

    42950

    浅谈设计模式 - 单例模式(一)

    优点: 可以节省系统资源只有真正使用的时候,才会进行获取 对于 缺点: 如果多线程并发访问会出现多次实例化的问题 实现代码: package com.zxd.interview.desginpattern.single...: 解释:序列化和反序列化的情况下,会出现问题,因为JAVA的序列化从磁盘读取的时候,会生成新的实例对象,但是这样就会违背单例模式的方式 实现代码: package com.zxd.interview.desginpattern.single...* 避免序列化和反序列化的对象为新实例破坏单例模式的规则 */ // protected Object readResolve(){ //...} } } 如果没有readResolve(),那么序列化之后反序列化是会变为一个新的实例,这样会破坏单例模式 如果存在readResolve(),那么序列化之后的对象就不会出现多个实例...扩展:为什么加入readResolve() 方法就可以避免序列化的问题 下面是关于《effective Java》的解释 ?

    69620

    写了这么久代码,你懂单例模式吗?

    ,但第一次加载时需要实例化,反映稍慢一些,而且在多线程不能正常工作。...,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,所以不建议用这种模式。...DCL虽然在一定程度解决了资源的消耗和多余的同步,线程安全等问题,但是他还是在某些情况会出现失效的问题,也就是DCL失效,在《java并发编程实践》一书建议用静态内部类单例模式来替代DCL。 5....反序列化操作提供了readResolve方法,这个方法可以让开发人员控制对象的反序列化。...{ return singleton; } 枚举单例的优点就是简单,但是大部分应用开发很少用枚举,可读性并不是很高,不建议用。

    44710

    Java之单例模式

    单例模式的优点: 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要 比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动 时直接产生一个单例对象,然后永久驻留内存的方式来解决...package com.ahzy; /** * 单例双重检测锁模式 * @author 晓宇码匠 * 问题:由于编译器优化原因和JVM底层模式内部原因,偶尔会出现数据调整问题,不建议使用 */ public...加载类时是线程 安全的。 instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性。 兼备了并发高效调用和延迟加载的优势!...(可以在构造方法中手动抛出异常控制) 可以通过定义readResolve()防止获得不同对象。 反序列化时,如果对象所在类定义了readResolve(),(实际是一种回调),定义返回哪个对象。...s = new SingletonDemo01(); } return s; } // 反序列化时,如果对象所在类定义了readResolve

    32120

    【高薪程序员必看】万字长文拆解Java并发编程!(7):不可变类设计指南

    运行时确定的final变量(如构造器初始化)存储于堆中对象实例。 引用类型:引用值本身不可变(存入常量表),但被引用对象内部状态可能可变。需配合不可变对象设计(深拷贝、防御性复制)实现真正不可变。...成员变量 存储细节:实例变量随对象头(存储哈希码、锁元数据)一起分配在堆中,对象实例大小受字段类型和内存对齐影响。 7.3....SerializationProxy(Immutable obj) { this.data = obj.data; } private Object readResolve...工具类支持 // 使用Guava的不可变集合 public static final ImmutableList COLORS = ImmutableList.of("Red"...i个连接跟传递的连接对象是同一个对象 if (connections[i] == connection) { //直接设置状态为0 因为操作当前连接的就是当前线程不会出现线程安全问题

    15800

    java安全编码指南之:序列化Serialization

    同样的,static表示的是类变量,也不需要被序列化。 注意serialVersionUID serialVersionUID 表示的是对象的序列ID,如果我们不指定的话,是JVM自动生成的。...readResolve和writeReplace 如果class中的字段比较多,而这些字段都可以从其中的某一个字段中自动生成,那么我们其实并不需要序列化所有的字段,我们只把那一个字段序列化就可以了,其他的字段可以从该字段衍生得到...序列化在非静态上下文中声明的内部类,该内部类包含对封闭类实例的隐式非瞬态引用,从而导致对其关联的外部类实例的序列化。 Java编译器对内部类的实现在不同的编译器之间可能有所不同。...加上一个readResolve方法就可以了: protected final Object readResolve() throws NotSerializableException {...如果readObject调用了可重写的方法,那么恶意代码就可以在方法的重写中获取到还未完全实例化的对象,可能造成问题。

    70721

    Java 设计模式 | 单例模式

    概述 单例模式,是设计模式中最常见的模式之一,它是一种创建对象模式,用于产生一个对象的具体实例,可以确保系统中一个类只会产生一个实例。...核心结构 单例模式的核心在于通过一个接口返回唯一的对象实例。...此时线程 B 抢占到 CPU 资源,执行第12 行的检测结果为 false,则执行第19行,从而返回一个还未初始化完成的 instance 对象,从而出导致问题出现。...readResolve() 方法后,readObject() 方法就已经形同虚设,它直接使用 readResolve() 替换了原本的返回值,从而从形式上构造了单例。...总结 在实际工作中,单例的使用还是比较常见的,在几种实现方式中,双重检测机制、静态内部类、枚举方式都是比较推荐。

    58920
    领券