内部锁池和等待池

17 篇文章 0 订阅
5 篇文章 0 订阅

1.内部锁

Java平台中,每个对象都有一个唯一与之对应的内部锁(Monitor)。Java虚拟机会为每个对象维护两个“队列”(姑且称之为“队列”,尽管它不一定符合数据结构上队列的“先进先出”原则):

  • 一个叫Entry Set(入口集)–>锁池
    • 对于任意的对象objectX,objectX的Entry Set用于存储等待获取objectX对应的内部锁的所有线程。
  • 一个叫Wait Set(等待集)–>等待池
    • objectX的Wait Set用于存储执行了objectX.wait()/wait(long)的线程。

2.锁池

假设线程A已经拥有了某个对象的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。

锁池

  • 当对象B的锁被其持有线程(这里就是A)释放时,锁池中的一个任意(注意是“任意”,而不一定是锁池等待时间最长或者最短的)线程会被唤醒(即线程的生命周期状态变更为RUNNABLE)。
  • 这个被唤醒的线程会与其他活跃线程(即不处于锁池之中,且线程的生命周期状态为RUNNABLE的线程)再次抢占对象B的锁。

3.等待池

假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁(因为wait()方法必须出现在synchronized中,这样自然在执行wait()方法之前线程A就已经拥有了该对象的锁),同时线程A就进入到了该对象的等待池中。如果另外的一个线程调用了相同对象的notifyAll()方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,准备争夺锁的拥有权。如果另外的一个线程调用了相同对象的notify()方法,那么仅仅有一个处于该对象的等待池中的线程(随机)会进入该对象的锁池。

等待池

  • 如果其中一个被唤醒的等待线程成功申请到锁,那么该线程就会从锁池移除。否则,这些被唤醒的线程移动在锁池中,以等待下次申请锁的机会。
  • 调用对象的 notifyAll方法后,等待池中的多个线程会被唤醒,但是这些被唤醒的线程如果没有得到对象B的锁,还会在锁池中待着。
  • wait()与notify()可以应用于同步执行中,对先后顺序有严格要求的场景中。
  • 比如消费者与生产者等等
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值