当前位置: 首页 > news >正文

Java单例模式总结

说明:单例模式的核心是确保一个类只有一个实例,并提供全局访问点。饿汉式和懒汉式是两种常见的实现方式

一、饿汉式和懒汉式

1. 饿汉式(Eager Initialization)

public class EagerSingleton {// 类加载时直接初始化实例private static final EagerSingleton instance = new EagerSingleton();// 私有构造方法,防止外部 new 实例private EagerSingleton() {}// 提供全局访问点public static EagerSingleton getInstance() {return instance;}
}

优点:

  • 线程安全:实例在类加载时创建,JVM 保证初始化过程的线程安全。
  • 实现简单:无需处理同步逻辑。

缺点:

  • 资源浪费:即使未使用,实例也会在程序启动时被创建。
  • 无法延迟加载:不适合初始化耗资源的场景。

2.懒汉式(Lazy Initialization)

代码实现(基础版,非线程安全):

public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}// 非线程安全!public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}

代码改进(双重检查锁定,线程安全):

public class ThreadSafeSingleton {private static volatile ThreadSafeSingleton instance; // volatile 禁止指令重排private ThreadSafeSingleton() {}public static ThreadSafeSingleton getInstance() {if (instance == null) { // 第一次检查synchronized (ThreadSafeSingleton.class) { // 加锁if (instance == null) { // 第二次检查instance = new ThreadSafeSingleton();}}}return instance;}
}

优点:

  • 延迟加载:实例在第一次使用时创建,节省资源。
  • 线程安全(双重检查版):通过同步块和 volatile 确保线程安全。

缺点:

  • 实现复杂:需处理双重检查锁定和 volatile 关键字。
  • 性能开销:同步锁可能影响高并发场景的性能(双重检查已优化)。

二、当前流行的单利模式

Kotlin 通过语言特性简化了单例模式的实现,提供两种主流方式:

1. 使用 object 关键字(饿汉式)

object Singleton {fun doSomething() {println("Kotlin object singleton")}
}// 调用方式
Singleton.doSomething()

特点:

  • 线程安全:由 JVM 保证初始化线程安全。
  • 饿汉式:实例在类加载时创建。
  • 代码极简:无需手动编写单例逻辑。

2. 使用 lazy 函数(懒汉式)

class LazySingleton private constructor() {companion object {val instance: LazySingleton by lazy {LazySingleton()}}fun doSomething() {println("Kotlin lazy singleton")}
}// 调用方式
LazySingleton.instance.doSomething()

特点:

  • 线程安全:lazy 默认使用 LazyThreadSafetyMode.SYNCHRONIZED 保证线程安全。
  • 延迟加载:实例在首次访问时创建。
  • 灵活性:可自定义初始化逻辑(如传递参数)。

推荐实践:

  • 在 Kotlin 中优先使用 objectlazy,避免手动实现单例逻辑。
  • 需要延迟加载时选择 lazy,否则直接使用 object
http://www.xdnf.cn/news/379873.html

相关文章:

  • 【Linux 系统调试】系统内存越界调试利器Electric Fence详解
  • waterfall与Bidding的请求机制
  • Day20打卡-奇异值SVD分解
  • Python序列化的学习笔记
  • 基于PE环境搭建及调试S32K312
  • Lua—元表(Metatable)
  • 怎样使自己处于高能量状态
  • Discriminative and domain invariant subspace alignment for visual tasks
  • JVM——即时编译器的中间表达形式
  • MYSQL 索引与数据结构笔记
  • 【大数据技术-HBase-关于Hmaster、RegionServer、Region等组件功能和读写流程总结】
  • 【Linux】线程POSIX信号量
  • JDBC工具类
  • c#建筑行业财务流水账系统软件可上传记账凭证财务管理系统签核功能
  • 代码随想录算法训练营第三十七天
  • win10-启动django项目时报错
  • ndk.symlinkdir - 在 Android Studio 3.5 及更高版本中,创建指向 NDK 的符号链接
  • 关于数据库查询速度优化
  • vue3使用tailwindcss报错问题
  • C.循环函数基础
  • 远程调试---在电脑上devtools调试运行在手机上的应用
  • PyTorch API 3 - mps、xpu、backends、导出
  • 6.秒杀优化
  • 更换内存条会影响电脑的IP地址吗?——全面解析
  • A2A大模型协议及Java示例
  • 以影像为笔,劳润智在世界舞台上书写艺术之路
  • 不同句子切割(文本分段 / chunking)工具或库 各自采用的策略和目标对比和分析
  • OLE(对象链接与嵌入)剪贴板内容插入到 CAD 图形中——CAD c# 二次开发
  • 非阻塞式IO-Java NIO
  • TCP Socket编程