并发编程 - lost wakeup

Java中wait()方法为什么要放在同步块中?(lost wake-up 问题):
https://www.cnblogs.com/sunweiye/p/11055550.html

lost wakeup问题

sleep 和 wakeup使用于等待某事发生,用于阻塞和唤醒线程的情形中。

所以sleep的使用逻辑是:检查状态,不符合则调用sleep阻塞当前线程;wakeup的使用逻辑是:改变状态,调用wakeup唤醒对应线程。

lost wakeup问题:(1)线程1首先检查状态,发现不符合。(2)线程2改变状态,调用wakeup方法。但是这时线程1还未调用sleep方法,其还未被阻塞,所以wakeup丢失。(3)最后线程1调用sleep方法,阻塞线程,且无法再被唤醒。

解决方案

  1. sleep 和 wakeup必须位于同一同步块中,且保证sleep方法保证释放锁和阻塞线程的原子性。线程1和线程2在检查/改变状态之前都要先获取锁,sleep方法调用时释放锁,保证线程2无法在线程1检查状态之后,调用sleep方法之前改变状态,并调用wakeup。

  2. sleep方法保证释放锁和阻塞线程的原子性在应用层面很难实现,所以JAVA AQS中先释放锁,再阻塞线程,所以还是会有lost wakeup问题。但是如果wakeup唤醒的对应线程还未被阻塞的话(即释放锁之后,阻塞线程之前),会重复调用wakeup函数,直到对应线程被阻塞,然后对其唤醒。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值