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

使用ReentrantLock替代CountDownLatch为何无法实现同等效果?

为什么你的ReentrantLock重写代码达不到CountDownLatch的效果?

哈哈,我一眼就看出问题所在啦!你这段ReentrantLock的代码完全没利用Condition的等待/唤醒机制,主线程根本没进入阻塞等待状态,自然不会等子线程执行完毕就直接往下跑了。咱们一步步拆解:

先回顾原CountDownLatch的核心逻辑

原代码里,主线程调用countDownLatch.await()后会立刻进入阻塞状态,一直等到子线程执行countDownLatch.countDown()把计数器从1减到0,主线程才会被唤醒,继续执行后面的打印逻辑。这是CountDownLatch专门为“等待一组线程完成”场景设计的机制。

你的ReentrantLock代码的问题点

  • 主线程没有阻塞逻辑:你写的主线程只是调用了lock()然后立刻unlock(),这两步几乎是瞬间完成的,没有任何让主线程停下来等待的代码,所以直接就执行到log.info("ReentrantLock: out thread..")了,完全不会等子线程。
  • Condition对象形同虚设:你虽然创建了Condition condition = lock.newCondition();,但从头到尾既没让主线程调用condition.await()(进入等待状态),也没让子线程调用condition.signal()/signalAll()(唤醒等待的主线程),这个Condition根本没发挥任何作用。

正确的ReentrantLock+Condition写法

要实现和原CountDownLatch一样的效果,你需要利用Condition的await()和signal()来手动实现等待-唤醒逻辑,代码应该是这样的:

public static void myReentrantLockFixed() {
    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    
    Thread t = new Thread(() -> {
        try {
            log.info("ReentrantLock: in thread..");
            Thread.sleep(3000);
            // 子线程执行完任务后,获取锁并唤醒主线程
            lock.lock();
            try {
                condition.signal();
            } finally {
                lock.unlock();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    
    lock.lock();
    try {
        t.start();
        // 主线程进入等待,释放锁,直到被子线程唤醒
        condition.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
    log.info("ReentrantLock: out thread..");
}

修正后的逻辑说明:

  1. 主线程先获取锁,调用condition.await():这会让主线程进入阻塞状态,同时自动释放锁,避免子线程无法获取锁。
  2. 子线程执行完任务后,先获取锁,调用condition.signal()唤醒主线程,然后释放锁。
  3. 主线程被唤醒后,会重新获取锁,然后继续执行后续代码,最后释放锁。

这样就能实现和原CountDownLatch代码完全一致的效果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:22:52