You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单例对象中method1与method2的线程并发控制问题求助

用ReentrantReadWriteLock结合Semaphore实现需求

你之前用synchronized修饰方法的问题在于,synchronized是独占锁,不管调用method1还是method2,同一时间只能有一个线程执行,完全限制了method1的并发能力。而ReentrantReadWriteLock正好能解决这个矛盾,它的读锁支持多线程并发持有,写锁独占,且读写锁互斥,再配合Semaphore就能限制method1的并发数为5。

具体实现代码

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

// 单例类示例
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock readLock = rwLock.readLock();
    private final Lock writeLock = rwLock.writeLock();
    private final Semaphore method1Semaphore = new Semaphore(5); // 限制method1最多5个线程并发

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }

    public void method1() {
        try {
            method1Semaphore.acquire(); // 先获取信号量,控制并发数
            readLock.lock(); // 获取读锁
            // --- 这里写method1的业务逻辑 ---
            System.out.println(Thread.currentThread().getName() + " 执行method1");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢复中断状态
        } finally {
            readLock.unlock(); // 释放读锁
            method1Semaphore.release(); // 释放信号量
        }
    }

    public void method2() {
        writeLock.lock(); // 获取写锁
        try {
            // --- 这里写method2的业务逻辑 ---
            System.out.println(Thread.currentThread().getName() + " 执行method2");
        } finally {
            writeLock.unlock(); // 释放写锁
        }
    }
}

逻辑说明

  1. 读写锁互斥:
    • 当method2持有写锁时,所有调用method1的线程会阻塞在readLock.lock(),直到写锁释放;
    • 当有线程持有读锁(即method1在执行)时,method2会阻塞在writeLock.lock(),直到所有读锁都被释放。
  2. Semaphore控制并发数:
    • method1Semaphore的许可数设为5,确保同一时间最多只有5个线程能进入method1的业务逻辑,满足你对method1的并发限制需求。
  3. 资源释放保障:
    • 锁和信号量的释放都放在finally块中,避免因异常导致锁未释放、信号量泄漏,防止死锁问题。

额外注意

  • 如果需要公平锁(让等待时间最长的线程优先获取锁),可以创建ReentrantReadWriteLock时传入true:new ReentrantReadWriteLock(true);
  • 单例模式要确保线程安全(示例中用饿汉式,本身是线程安全的),避免多个实例导致锁失效。

内容的提问来源于stack exchange,提问作者user21338878

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:03:32