欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 线程安全的单例模式(Singleton)。

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

2025/5/18 16:19:00 来源:https://blog.csdn.net/Good_tea_h/article/details/143448698  浏览:    关键词:线程安全的单例模式(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关键字和指令重排序的问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com