IT评测·应用市场-qidao123.com

标题: 懒汉式单例模式 [打印本页]

作者: 勿忘初心做自己    时间: 2025-1-17 00:19
标题: 懒汉式单例模式
懒汉式单例是一种在需要时才会初始化实例的单例模式实现方式,适用于需要延迟加载的场景。以下是一个现实使用懒汉式单例的例子,并结合适用场景进行分析。

示例场景:日志管理器

在开发过程中,日志记录是一个常见需求,通常日志记录器在整个应用中只需要一个实例。使用懒汉式单例可以确保日志管理器只在第一次需要时进行初始化,从而节省体系资源。
懒汉式单例完整代码

  1. public class LogManager {
  2.     // 1. 静态变量,保存唯一实例,但不立即初始化
  3.     private static LogManager instance = null;
  4.     // 2. 私有构造方法,防止外部实例化
  5.     private LogManager() {
  6.         System.out.println("LogManager initialized!");
  7.     }
  8.     // 3. 提供一个静态方法访问唯一实例
  9.     public static synchronized LogManager getInstance() {
  10.         if (instance == null) {
  11.             instance = new LogManager();  // 延迟实例化
  12.         }
  13.         return instance;
  14.     }
  15.     // 4. 示例方法,用于记录日志
  16.     public void log(String message) {
  17.         System.out.println("Log: " + message);
  18.     }
  19. }
复制代码

代码分析


使用示例

假设我们需要记录一些紧张的操纵日志,可以通过以下代码来使用 LogManager:
  1. public class Main {
  2.     public static void main(String[] args) {
  3.         // 第一次调用时实例化 LogManager
  4.         LogManager logger1 = LogManager.getInstance();
  5.         logger1.log("This is the first log message.");
  6.         // 第二次调用时直接返回已有实例
  7.         LogManager logger2 = LogManager.getInstance();
  8.         logger2.log("This is the second log message.");
  9.         // 比较两个实例
  10.         System.out.println("Are logger1 and logger2 the same instance? " + (logger1 == logger2));
  11.     }
  12. }
复制代码

输出结果

  1. LogManager initialized!
  2. Log: This is the first log message.
  3. Log: This is the second log message.
  4. Are logger1 and logger2 the same instance? true
复制代码
说明:



懒汉式单例的优缺点

优点

缺点


改进方案:双重查抄锁定(Double-Checked Locking)

为了办理同步带来的性能问题,可以使用双重查抄锁定优化懒汉式单例:
  1. public class LogManager {
  2.     // 1. 静态变量,使用 volatile 修饰以保证可见性
  3.     private static volatile LogManager instance = null;
  4.     // 2. 私有构造方法
  5.     private LogManager() {
  6.         System.out.println("LogManager initialized!");
  7.     }
  8.     // 3. 提供静态方法,使用双重检查锁定
  9.     public static LogManager getInstance() {
  10.         if (instance == null) { // 第一次检查
  11.             synchronized (LogManager.class) {
  12.                 if (instance == null) { // 第二次检查
  13.                     instance = new LogManager();
  14.                 }
  15.             }
  16.         }
  17.         return instance;
  18.     }
  19.     // 示例功能
  20.     public void log(String message) {
  21.         System.out.println("Log: " + message);
  22.     }
  23. }
复制代码
优势


扩展1 — 双重查抄锁定

这段代码是一个双重查抄锁定(Double-Checked Locking)实现的懒汉式单例模式的核心部分,它旨在办理多线程环境下单例实例创建的线程安全问题,同时优化性能。下面是对这段代码的详细分析:
Why Double-Checked Locking?

扩展2 — 使用 volatile

为了完全包管双重查抄锁定的精确性,instance 应该使用 volatile 关键字声明:
  1. private static volatile LogManager instance = null;
复制代码

双重查抄锁定模式是实现懒汉式单例的一种高效方式,适用于性能要求较高的多线程环境。但是,它的精确实现依赖于 volatile 关键字来防止重排序问题。通过这种方式,我们可以在包管线程安全的同时,尽量减少同步带来的性能损耗。

总结

懒汉式单例适合于需要延迟加载且实例化成本较高的场景(如日志管理器、配置加载器等)。在并发场景下,最好使用线程安全的实现,例如同步方法版或双重查抄锁定版,以确保唯一实例的精确性和性能的平衡。

   
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4