线程安全的单例模式

  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 实例。

相关推荐
不当菜虚困6 分钟前
JAVA设计模式——(四)门面模式
java·开发语言·设计模式
ruyingcai6666666 分钟前
用python进行OCR识别
开发语言·python·ocr
m0Java门徒14 分钟前
面向对象编程核心:封装、继承、多态与 static 关键字深度解析
java·运维·开发语言·intellij-idea·idea
liuweidong080216 分钟前
【Pandas】pandas DataFrame radd
开发语言·python·pandas
无心水39 分钟前
【Java面试笔记:基础】8.对比Vector、ArrayList、LinkedList有何区别?
java·笔记·面试·vector·arraylist·linkedlist
农民也会写代码1 小时前
dedecms织梦arclist标签noflag属性过滤多个参数
开发语言·数据库·sql·php·dedecms
创码小奇客1 小时前
MongoDB 时间序列:解锁数据时光机的终极指南
java·mongodb·trae
黯_森1 小时前
Java面向对象
java·后端
代码小侦探1 小时前
Java中以Maven方式引入Oracle JDBC Driver依赖的详解
java·oracle·maven
不畏惧的少年1 小时前
AQS的底层实现原理
java