单例模式
2023-08-13 22:06 tonyniu8 阅读(10) 评论(0) 编辑 收藏 举报双重锁
解释
- 双重if是需要的。
如果只有一重,还是可能初始化两次 - valatile是要得。
uniqueInstance = new Singleton();
这段代码其实是分为三步执行:
- 为 uniqueInstance 分配内存空间
- 初始化 uniqueInstance
- 将 uniqueInstance 指向分配的内存地址
但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1>3>2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。
使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。
if (uniqueInstance == null) {
synchronized (Singleton.class) {
uniqueInstance = new Singleton();
}
}
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
静态内部类
//静态内部类加载时不会加载。
//只有调用时,才会调用。
//这种方式不仅具有延迟初始化的好处,由jvm只初始一个
package com.java.design.pattern;
//静态内部类
//由jvm只初始一个
public class Singleton1 {
private Singleton1(){}
private static class SingletonHolder{
private static final Singleton1 INSTANCE=new Singleton1();
}
public static Singleton1 getUniqueInstance(){
return SingletonHolder.INSTANCE;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2021-08-13 https SSL/TLS协议运行机制的概述