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

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

以上是个人理解,如果有误,请在评论区中指正!

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
先进先出对象是一种常用的对象实现方式,其基本思想是将对象以先进先出的顺序存储在一个队列,当需要获取对象时,从队列的头部取出一个对象,当需要归还对象时,将对象放回队列的尾部。下面是一个简单的Java实现示例: ```java import java.util.LinkedList; public class FIFOObjectPool<T> { private final LinkedList<T> pool = new LinkedList<>(); private final Object lock = new Object(); public void addObject(T object) { synchronized (lock) { pool.addLast(object); lock.notify(); } } public T getObject() throws InterruptedException { synchronized (lock) { while (pool.isEmpty()) { lock.wait(); } return pool.removeFirst(); } } public void returnObject(T object) { synchronized (lock) { pool.addLast(object); lock.notify(); } } } ``` 在上面的实现,我们使用了Java的LinkedList来作为对象的容器,并使用一个锁来保证线程安全。当需要添加对象时,我们使用addLast方法将对象添加到队列的尾部,并使用notify方法通知等待的线程。当需要获取对象时,我们使用while循环来等待队列非空,并使用removeFirst方法从队列头部获取对象。当需要归还对象时,我们使用addLast方法将对象放回队列的尾部,并使用notify方法通知等待的线程。 需要注意的是,在使用对象时,需要确保对象的对象都是可重用的,并且在使用完毕后,需要及时将对象归还到对象,以便下次使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值