线程安全的单例模式(Singleton)。

在Java中,实现线程安全的单例模式(Singleton)通常涉及确保类的实例在多线程环境中只被创建一次。有多种方法可以实现这一点,包括使用synchronized关键字、双重检查锁定(Double-Checked Locking, DCL)、静态内部类(Bill Pugh Singleton Design)以及使用java.util.concurrent包中的类。

以下是几种常见的线程安全单例模式实现:

1. 饿汉式(Eager Initialization)

饿汉式在类加载时就完成了实例的创建,因此是线程安全的。

|---|---------------------------------------------------------------|
| | public class Singleton { |
| | private static final Singleton INSTANCE = new Singleton(); |
| | |
| | // 私有构造函数防止实例化 |
| | private Singleton() {} |
| | |
| | public static Singleton getInstance() { |
| | return INSTANCE; |
| | } |
| | } |

2. 懒汉式(Lazy Initialization),使用synchronized方法

这种方法在需要时才创建实例,但整个getInstance方法是同步的,可能会影响性能。

|---|---------------------------------------------------------|
| | public class Singleton { |
| | private static Singleton instance; |
| | |
| | // 私有构造函数防止实例化 |
| | private Singleton() {} |
| | |
| | public static synchronized Singleton getInstance() { |
| | if (instance == null) { |
| | instance = new Singleton(); |
| | } |
| | return instance; |
| | } |
| | } |

3. 双重检查锁定(Double-Checked Locking)

这种方法结合了懒汉式的延迟初始化和饿汉式的性能优势,通过减少同步代码块的范围来提高性能。

|---|------------------------------------------------|
| | public class Singleton { |
| | private static volatile Singleton instance; |
| | |
| | // 私有构造函数防止实例化 |
| | private Singleton() {} |
| | |
| | public static Singleton getInstance() { |
| | if (instance == null) { // 第一次检查,无需同步 |
| | synchronized (Singleton.class) { |
| | if (instance == null) { // 第二次检查,需要同步 |
| | instance = new Singleton(); |
| | } |
| | } |
| | } |
| | return instance; |
| | } |
| | } |

注意:这里使用了volatile关键字来确保instance变量的可见性,并禁止指令重排序。

4. 静态内部类(Bill Pugh Singleton Design)

这种方法利用了类加载机制来保证线程安全和延迟加载。

|---|---------------------------------------------------------------|
| | public class Singleton { |
| | private Singleton() {} |
| | |
| | private static class SingletonHelper { |
| | private static final Singleton INSTANCE = new Singleton(); |
| | } |
| | |
| | public static Singleton getInstance() { |
| | return SingletonHelper.INSTANCE; |
| | } |
| | } |

5. 使用java.util.concurrent.locks.Lock

这种方法使用Java并发包中的Lock接口来提供显式的锁控制。

|---|----------------------------------------------------------|
| | import java.util.concurrent.locks.Lock; |
| | import java.util.concurrent.locks.ReentrantLock; |
| | |
| | public class Singleton { |
| | private static Singleton instance; |
| | private static final Lock lock = new ReentrantLock(); |
| | |
| | // 私有构造函数防止实例化 |
| | private Singleton() {} |
| | |
| | public static Singleton getInstance() { |
| | lock.lock(); |
| | try { |
| | if (instance == null) { |
| | instance = new Singleton(); |
| | } |
| | } finally { |
| | lock.unlock(); |
| | } |
| | return instance; |
| | } |
| | } |

6. 使用java.util.concurrent.atomic.AtomicReference

这种方法利用了原子变量来确保线程安全的延迟初始化。

|---|--------------------------------------------------------------------------------------------|
| | import java.util.concurrent.atomic.AtomicReference; |
| | |
| | public class Singleton { |
| | private static final AtomicReference<Singleton> INSTANCE_REF = new AtomicReference<>(); |
| | |
| | // 私有构造函数防止实例化 |
| | private Singleton() {} |
| | |
| | public static Singleton getInstance() { |
| | Singleton instance = INSTANCE_REF.get(); |
| | if (instance == null) { |
| | synchronized (Singleton.class) { |
| | instance = INSTANCE_REF.get(); |
| | if (instance == null) { |
| | instance = new Singleton(); |
| | INSTANCE_REF.set(instance); |
| | } |
| | } |
| | } |
| | return instance; |
| | } |
| | } |

然而,这种方法实际上是双重检查锁定的一个变种,但它使用了AtomicReference来封装实例变量。在实际应用中,直接使用静态内部类或双重检查锁定通常更为简洁和高效。

总结

对于大多数应用场景,静态内部类方法(Bill Pugh Singleton Design)是首选,因为它既简单又高效,同时保证了线程安全和延迟加载。双重检查锁定也是一个不错的选择,但需要小心处理volatile关键字和指令重排序的问题。

相关推荐
萧曵 丶8 小时前
懒加载单例模式中DCL方式和原理解析
java·开发语言·单例模式·dcl
萧曵 丶8 小时前
单例模式 7 种实现方式对比表
java·单例模式
当战神遇到编程4 天前
图书管理系统
java·开发语言·单例模式
Remember_9934 天前
Java 单例模式深度解析:设计原理、实现范式与企业级应用场景
java·开发语言·javascript·单例模式·ecmascript
春日见5 天前
win11 分屏设置
java·开发语言·驱动开发·docker·单例模式·计算机外设
短剑重铸之日5 天前
《设计模式》第二篇:单例模式
java·单例模式·设计模式·懒汉式·恶汉式
钦拆大仁7 天前
Java设计模式-单例模式
java·单例模式·设计模式
老骥伏枥~7 天前
VB.NET 中的单例模式
单例模式·.net
「QT(C++)开发工程师」7 天前
C++ 多种单例模式
java·c++·单例模式
一路往蓝-Anbo7 天前
第 2 篇:单例模式 (Singleton) 与 懒汉式硬件初始化
开发语言·数据结构·stm32·单片机·嵌入式硬件·链表·单例模式