Java ReentrantLock Condition condition2调用await()方法挂起时报错IllegalMonitorStateException

Java ReentrantLock condition2调用await()方法挂起时报错IllegalMonitorStateException

输出:

t1 Start
t2 Start
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(AbstractQueuedSynchronizer.java:1723)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2036)
    at Main.lambda$main$1(Main.java:28)
    at java.lang.Thread.run(Thread.java:750)

源码:

public class Main {
    public static void main(String[] args) throws IOException {

        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Condition condition2 = lock.newCondition();
        
        Test c = new Main().new Test();
        Thread t1 = new Thread(()->{
            System.out.println("t1 Start");
            lock.tryLock();
            try {
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
            System.out.println("t1 End");});
        Thread t2 = new Thread(()->{
            System.out.println("t2 Start");
            lock.tryLock();
            try {
                condition2.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
            System.out.println("t2 End");});
        t1.start();
        t2.start();

        lock.tryLock();
        condition.signal();
        lock.unlock();
    }

该回答引用自ChatGPT

问题在于,当调用condition2.await()时,当前线程并没有获取condition2对应的锁,而是获取了之前创建的lock的锁。因此,在调用condition2.await()之前,需要先获取condition2对应的锁。
修改代码如下:

Thread t2 = new Thread(()->{
    System.out.println("t2 Start");
    lock.lock();
    try {
        condition2.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    lock.unlock();
    System.out.println("t2 End");
});