单例模式
单例模式属于创建型模式,⼀个单例类在任何情况下都只存在⼀个实例,
构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀
个静态公有⽅法获取实例。
双重检查锁(double check locking)
public class LazySingleton {
//volatile防止指令重排序
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
//第一次检查,确保不必要的同步
if (instance == null) {
synchronized (LazySingleton.class) {
//第二次检查,确保只有一个线程创建实例
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
-
懒汉式,懒加载,使用的时候才创建对象
-
双重检查指两次非空判断,锁指的
synchronized
加锁- 第一重判断,如果实例已经存在,无需进行同步操作
- 第二重判断,有多个线程一起到达锁位置时,对锁竞争,其中一个线程获取锁后,第一次进入会判断实例为null,从而创建对象。完成后释放锁,其他线程获取锁后会被判定非空拦截,直接返回单例对象
-
synchronized同步代码块作用,防止有多个线程同时调用时,导致生成多个实例。有了同步块,每次只有1个线程能访问同步块内容。当第一个抢到锁线程创建实例后,之后的调用都不会进入同步块
-
volatile关键字作用:可见性、防止指令重排序。用new创建对象时,其实是三步操作,不是原子操作:
- 1.在堆内存申请空间
- 2.调用构造方法,初始化对象
- 3.将引用变量指向堆内存空间
为提高性能,处理器可能对代码执行顺序重新排序,如果运行顺序为
1 3 2
,当引用变量指向内存空间时,这个对象不为null,但是还没初始化,其他线程在调用getInstance
方法使用时,会判断instance
不为null,导致错误使用,出现异常
饿汉式
在类加载阶段就创建实例了
public class EagerSingleton {
private final static EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
- 线程安全,没加锁,效率高
- 缺点是类加载就初始化,浪费内存空间
有关创建型设计模式的内容就更新到这了,下一篇更新结构型设计模式的内容
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~