Java中的锁池和等待池

Java平台中,因为有内置锁的机制,每个对象都可以承担锁的功能。Java虚拟机会为每个对象维护两个“队列”(姑且称之为“队列”,尽管它不一定符合数据结构上队列的“先进先出”原则):一个叫Entry Set(入口集),另外一个叫Wait Set(等待集)。对于任意的对象objectX,objectX的Entry Set用于存储等待获取objectX这个锁的所有线程,也就是传说中的锁池,objectX的Wait Set用于存储执行了objectX.wait()/wait(long)的线程,也就是等待池。

先来一张线程的状态图:

设objectX是任意一个对象,假设有线程A、B、C同时申请objectX这个对象锁,那么由于任意一个时刻只有一个线程能够获得(占用/持有)这个锁,因此除了胜出(即获得了锁)的线程(这里假设是B)外,其他线程(这里就是A和C)都会被暂停(线程的生命周期状态会被调整为BLOCKED)。这些因申请锁而落选的线程就会被存入objectX对应的锁池之中。当objectX被其持有线程(这里就是B)释放时,锁池中的一个任意(注意是“任意”,而不一定是锁池中等待时间最长或者最短的)线程会被唤醒(即线程的生命周期状态变更为RUNNABLE)。这个被唤醒的线程会与其他活跃线程(即不处于锁池之中,且线程的生命周期状态为RUNNABLE的线程)再次抢占objectX。这时,被唤醒的线程如果成功申请到objectX,那么该线程就从锁池中移除。否则,被唤醒的线程仍然会停留在锁池中,并再次被暂停,以等待下次申请锁的机会。

如果有个线程执行了objectX.wait(),那么该线程就会被暂停(线程的生命周期状态会被调整为Blocked),并且会释放掉objectX锁,然后被存入objectX的等待池之中。此时,该线程就被称为objectX的等待线程。当其他线程执行了objectX.notify()/notifyAll()时,等待池中的一个(或者多个,取决于被调用的是notify还是notifyAll方法)任意(注意是“任意”,而不一定是等待池中等待时间最长或者最短的)等待线程会被唤醒,这些被唤醒的线程会被放到锁池中,会与锁池中已经存在的线程以及其他(可能的)活跃线程共同参与抢夺objectX。至于代码中到底是使用notify还是notifyAll方法,这个要根据实际情况来分析。

ps:等待池中的线程被notify()或者notifyAll()方法唤醒进入到锁池,最后竞争到了锁并且进入了Running状态的话,会从wait现场恢复,执行wait()方法之后的代码。

以上是个人理解,如果有误,请在评论区中指正!
---------------------
作者:雪飘雪融
来源:CSDN
原文:https://blog.csdn.net/qq_22498277/article/details/82184419?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值