线程安全的单例模式

  1. 使用 synchronized 修饰 getInstance 方法

确保了只有一个线程可以同时访问 getInstance 方法。这意味着在任何时候只有一个线程可以执行 getInstance() 方法,从而避免了多个线程同时创建多个实例的情况,因此是线程安全的。

java 复制代码
public class ClientUtil {
    private static ClientUtil clientUtil;

    private ClientUtil() {}

    public static synchronized ClientUtil getInstance() {
        if (null == clientUtil) {
            clientUtil = new ClientUtil();
            clientMap = new HashMap<String, ApiClient>();
        }
        return clientUtil;
    }
}

但是,这种实现方式会在每次调用 getInstance() 方法时都获取锁,这可能会影响性能,尤其是在高并发的情况下。因为只有一个线程可以访问该方法,其他线程必须等待当前线程释放锁才能继续执行。

  1. 使用双重检查锁定(Double-Checked Locking)机制 优化性能

核心思想是在首次检查对象是否为 null 时进行同步,以确保只有一个线程可以创建对象,而后续的检查则不需要同步,以提高性能。

java 复制代码
public class ThreadSafeSingleton {

    // 私有静态变量,存储单例实例
    private static volatile ThreadSafeSingleton instance;

    // 私有构造函数,防止外部实例化
    private ThreadSafeSingleton() {}

    // 公有静态方法,获取单例实例
    public static ThreadSafeSingleton getInstance() {
        // 双重检查锁定,确保只有一个线程创建实例
        if (instance == null) {
            synchronized (ThreadSafeSingleton.class) {
                // 再次检查实例是否已经被创建
                if (instance == null) {
                    instance = new ThreadSafeSingleton();
                }
            }
        }
        return instance;
    }

    // 其他业务方法
    public void doSomething() {
        System.out.println("Singleton instance is doing something.");
    }
}

instance 变量使用了 volatile 关键字,确保多线程环境下对它的读取和写入操作都是原子的,并且对所有线程可见。

构造函数 ThreadSafeSingleton() 被声明为私有,确保外部无法直接实例化 ThreadSafeSingleton。

getInstance() 方法使用了双重检查锁定机制,在多线程环境下保证了只有一个线程创建实例。首先检查 instance 是否为 null,如果为 null,则进入同步块,再次检查 instance 是否为 null,如果仍然为 null,则创建一个新的 ThreadSafeSingleton 实例。

相关推荐
ProtonBase1 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
Watermelo6172 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v7 分钟前
leetCode43.字符串相乘
java·数据结构·算法
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J2 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB2 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
计算机学长大白3 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
suweijie7683 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿4 小时前
List深拷贝后,数据还是被串改
java