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

Java ReentrantLock中Condition await()的锁释放机制咨询

问题解答

你的理解完全正确:cond.await()会让持有锁的ThreadOne进入等待状态,同时主动释放持有的ReentrantLock,这就是两个场景执行顺序不同的核心原因。下面分别拆解两种场景的执行逻辑:

场景一:调用cond.await()的情况

  1. ThreadOne先执行,通过lock.lock()获取到ReentrantLock,打印Waiting 1 ....
  2. 调用cond.await():此时ThreadOne会主动释放持有的锁,同时进入Condition的等待队列,暂停执行
  3. ThreadTwo休眠1秒后尝试获取锁,因为ThreadOne已经释放锁,所以成功获取,打印Waiting 2 ....
  4. 等待用户输入回车后,ThreadTwo调用cond.signal()唤醒等待队列中的ThreadOne,但此时ThreadTwo仍持有锁,所以ThreadOne虽被唤醒,仍需等待ThreadTwo释放锁才能继续执行
  5. ThreadTwo执行完increment()后,在finally块中调用lock.unlock()释放锁
  6. 锁释放后,ThreadOne重新获取锁,继续执行后续代码:打印Woken up!、执行increment(),最后释放锁

场景二:注释掉cond.await()的情况

  1. ThreadOne调用lock.lock()获取锁后,因为没有调用await(),不会释放锁,直接打印Waiting 1 ....和Woken up!
  2. ThreadOne完整执行完increment()后,才在finally块中调用lock.unlock()释放锁
  3. ThreadTwo在此之前尝试获取锁时,会因锁被ThreadOne持有而进入阻塞状态,直到ThreadOne释放锁后,才能获取锁并执行自身逻辑

第一段代码(带cond.await())

public class ExecProgram {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    private Condition cond = lock.newCondition();

    private void increment(String threadName) {
        for (int i = 0; i < 5; i++) {
            count++;
            System.out.println("Incremented by "+threadName);
        }
    }

    public void ThreadOne() throws InterruptedException {
        lock.lock();
        System.out.println("Waiting 1 ....");
        cond.await();
        System.out.println("Woken up!");
        try {
            increment("Thread1");
        } finally {
            System.out.println("Waiting done 1 ....");
            lock.unlock();
        }
    }

    public void ThreadTwo() throws InterruptedException {
        Thread.sleep(1000);
        lock.lock();
        System.out.println("Waiting 2 ....");
        System.out.println("Press the return key!");
        new Scanner(System.in).nextLine();
        System.out.println("Rcvd return key!");
        cond.signal();
        try {
            increment("Thread2");
        } finally {
            System.out.println("Waiting done 2 ....");
            //should be written to unlock Thread whenever signal() is called
            lock.unlock();
        }
    }

    public void finished() {
        System.out.println("Count is: " + count);
    }
}

第一段输出

Waiting 1 ....
Waiting 2 ....
Press the return key!

Rcvd return key!
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Waiting done 2 ....
Woken up!
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Waiting done 1 ....
Count is: 10
Time taken 4112

第二段代码(注释掉cond.await()及相关代码)

public void ThreadOne() throws InterruptedException {
    lock.lock();
    System.out.println("Waiting 1 ....");
//    cond.await();
    System.out.println("Woken up!");
    try {
        increment("Thread1");
    } finally {
        System.out.println("Waiting done 1 ....");
        lock.unlock();
    }
}
public void ThreadTwo() throws InterruptedException {
//    Thread.sleep(1000);
    lock.lock();
    System.out.println("Waiting 2 ....");
/*    System.out.println("Press the return key!");
    new Scanner(System.in).nextLine();
    System.out.println("Rcvd return key!");
    cond.signal(); */
    try {
        increment("Thread2");
    } finally {
        System.out.println("Waiting done 2 ....");
        //should be written to unlock Thread whenever signal() is called
        lock.unlock();
    }
}

第二段输出

Waiting 1 ....
Woken up!
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Incremented by Thread1
Waiting done 1 ....
Waiting 2 ....
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Incremented by Thread2
Waiting done 2 ....
Count is: 10
Time taken 11

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:42:03