AQS-为什么说调用await()方法的线程一定要持有锁?

   日期:2020-07-10     浏览:92    评论:0    
核心提示:没持有锁的线程调用await()方法的测试代码:public static void main(String[] args) { Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); try { condition.await(); } catch (InterruptedException e) { e.printStackTrace();

没持有锁的线程调用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()方法的线程一定要持有锁。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服