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

线程安全的单例模式(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关键字和指令重排序的问题。


http://www.mrgr.cn/news/64052.html

相关文章:

  • 从技术与市场角度看:3D 创作软件与信创系统的 “距离”
  • 功能强大视频编辑软件 Movavi Video Editor Plus 2024 v24.2.0 中文特别版
  • 蓝牙BLE开发——红米手机无法搜索蓝牙设备?
  • 机器人和智能的进化速度远超预期-ROS-AI-
  • 基于java+SpringBoot+Vue的网上租贸系统设计与实现
  • 练习LabVIEW第二十七题
  • 基于Python可视化的热门微博数据分析系统
  • WPF 实现冒泡排序可视化
  • nfs服务器
  • TPP-PEG-N3叠氮-聚乙二醇-四苯基吡嗪,功能话聚乙二醇,PEG分子量可定制
  • 打造一个带报时功能的卡通数字时钟 —— 使用Python和Tkinter
  • 【松下PLC.通信】——威卡力传感器如何和松下PLC进行Free协议的通讯
  • 域名购买需要多少钱
  • Spring Boot框架在信息学科平台开发中的高级应用
  • 真题与解析 202206三级 青少年软件编程(Python)考级
  • Nat Med病理AI系列|哈佛大学团队发表研究,探讨深度学习在病理诊断中的公平性问题及解决方案|顶刊精析·24-11-02
  • 从零开始学AIStarter:创作者模式全攻略【AI工作流、数字人、大模型、对话、设计...】
  • 【生物学&水族馆】观赏淡水鱼检测系统源码&数据集全套:改进yolo11-dysample
  • 2024年华为OD机试真题-最小的调整次数-Python-OD统一考试(E卷)
  • 第三百零九节 Java JSON教程 - JSON语法
  • 平安养老险党委书记、董事长甘为民: “养老金融”大发展正当其时,空间广阔
  • Spring Boot详解:从入门到精通
  • 最全面的AI大模型面试题集合,存一下吧很难找全的!
  • [含文档+PPT+源码等]精品基于PHP实现的鲜花批发销售网站的设计与实现
  • 运维工程师运维管理文档,运维建设方案,运维整体配套资料(word原件整套)
  • 阿里国际2025届校园招聘 0826算法岗笔试