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

Java多线程实现读写者问题时Thread.sleep阻塞读线程问题咨询

问题根因定位

你遇到的首个读者休眠期间其余读者无法进入的问题,本质是读操作错误加了排他锁,或者读者计数的同步逻辑范围错误,常见错误场景包括:

  • 直接给读方法加了synchronized修饰,导致同一时间仅能有一个线程进入读方法
  • 误将实际读操作代码块包在了读者计数更新的同步块中,第一个读者持有同步锁休眠,其余读者无法更新计数获取读权限

读写者问题核心实现逻辑(读者优先版本示例)

核心依赖3个变量:

  • int readCount:记录当前正在执行读操作的线程数,初始为0
  • ReentrantLock countLock:仅用于保护readCount计数更新的线程安全
  • ReentrantLock writeLock:实现读写互斥、写写互斥的全局锁

读操作核心代码

public void read() throws InterruptedException {
    // 仅更新计数时加计数锁
    countLock.lock();
    try {
        readCount++;
        // 第一个读者获取写锁,阻塞所有写线程
        if (readCount == 1) {
            writeLock.lock();
        }
    } finally {
        countLock.unlock();
    }

    // 实际读逻辑完全在同步块之外,多个读者可同时执行
    try {
        System.out.println(Thread.currentThread().getName() + " 开始读取数据");
        Thread.sleep(5000); // 此处休眠不会阻塞其他读者进入
        System.out.println(Thread.currentThread().getName() + " 读取数据完成");
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        // 读结束更新计数
        countLock.lock();
        try {
            readCount--;
            // 最后一个读者释放写锁,允许写线程进入
            if (readCount == 0) {
                writeLock.unlock();
            }
        } finally {
            countLock.unlock();
        }
    }
}

写操作核心代码

public void write() throws InterruptedException {
    writeLock.lock();
    try {
        System.out.println(Thread.currentThread().getName() + " 开始写入数据");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName() + " 写入数据完成");
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        writeLock.unlock();
    }
}

实现正确性校验点

你可以对照自己的代码逐项检查:

  • 实际读逻辑是否在countLock的同步块之外,读操作期间不会持有任何排他锁
  • 所有锁的释放逻辑都放在finally块中,避免异常导致锁泄漏引发死锁
  • 如果使用Object.wait/notify实现,条件判断必须放在循环中,处理虚假唤醒场景
  • 捕获InterruptedException后正确恢复了线程中断状态,没有吞中断异常

优化方向

  • 解决读者饥饿问题:默认读者优先实现中如果读线程持续存在,写线程会永远抢不到锁,可以切换为公平锁模式,或者实现写者优先、公平读写的版本
  • 性能优化:Java 8及以上版本可以用StampedLock替代普通重入锁,支持乐观读模式,读多写少场景下吞吐量提升非常明显
  • 增加超时机制:加锁时设置超时时间,避免极端场景下的死锁问题
  • 增加可观测性:埋点统计当前读线程数、等待的读写线程数,方便线上问题排查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:48:02