没持有锁的线程调用await()方法的测试代码:
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
结果如下:
接下来分析下为什么会报出IllegalMonitorStateException异常?
先跟进await()方法中:
发现逻辑执行到fullyRelease()方法里就中断了,跟进fullyRelease()方法中:
通过断点会发现逻辑执行到release()方法里就被中断了,继续跟进release()方法里:
通过断点会发现逻辑执行到tryRelease()方法里就被中断了,继续跟进tryRelease()方法里,以下是ReentrantLock类对tryRelease()方法的实现:
最后发现异常就是红框部分抛出的。
那么为什么会抛出这个异常呢,可以看下抛出这个异常的判断【Thread.currentThread() != getExclusiveOwnerThread()】的结果要是true,就会抛出IllegalMonitorStateException异常。
Thread.currentThread()取得的是当前线程对象,那么getExclusiveOwnerThread()方法取得的是什么,看看getExclusiveOwnerThread()方法:
这里的exclusiveOwnerThread对象就代表着持有锁的线程对象,所以【Thread.currentThread() != getExclusiveOwnerThread()】结果返回true就代表着持有锁的线程不是当前线程,那么就抛出IllegalMonitorStateException异常。
总结
为什么调用await()方法的线程一定要持有锁,可以这样简单的去理解,因为调用await()方法的线程会释放锁,不持有锁又怎么能够做释放锁的操作,所以调用await()方法的线程一定要持有锁。