Java等待-通知机制

Java等待-通知机制

现实世界中的就医流程拥有着完善的等待 - 通知机制,对比该就医流程能更好的理解和应用并发编程中的等待 - 通知机制。

基本就医流程:

  1. 患者去挂号,然后到就诊门口分诊,等待叫号。
  2. 叫到自己号时,可以找大夫就诊(获取到锁)。
  3. 就诊过程中医生可能会让患者去做检查,同时叫下一位患者(不满足条件释放锁,线程进入等待状态)。
  4. 当患者做完检查后,拿报告重新分诊等待叫号(满足条件等待获取锁)。
  5. 当大夫再次叫到号时患者再去找大夫就诊(获取到锁)。


用synchronized实现等待 - 通知机制,synchronized配合wait(),notify(),notifyAll()

等待队列和互斥锁是一对一的关系,每个互斥锁都有自己独立的等待队列。

在并发程序中,当一个线程进入临界区后,由于某些条件不满足,需要进入等待状态,Java对象的wait()方法就能够满足这种需求,当调用wait()方法后,当前线程就会被阻塞,并且进入到右边的等待队列当中,线程进入等待队列的同时会释放持有的互斥锁,线程释放锁之后其他线程就有机会获得锁并进入临界区了。

当线程要求的条件满足时可以用notify()和notifyAll()方法唤醒线程。

当条件满足时调用notify()会通知等待队列中的线程,告诉它条件曾经满足过。因为notify()只能保证在通知时间点,条件是满足的,被通知的线程的执行时间点和通知的时间点基本上不会吻合,所以当线程执行的时候很可能条件已经不满足了。

class Allocator{
    private List<Object> als;
    
    //一次性申请所有资源
    synchronized void apply(Object from,Object  to){
        //经典写法
        while(als.contains(from) || als.contains(to)){
            try{
                wait();
            }catch(Exception e) {

            }
        }
        als.add(from);
        als.add(to);
    }

    //归还资源
    synchronized void free(Object from,Object  to){
        als.remove(from);
        als.remove(to);
        notifyAll();
    }   
}

notify()是会随机的通知等待队列中的一个线程,而notifyAll()会通知等待队列中的所有线程,实际上使用notify(0很有风险,它的风险在于可能导致某些线程永远不会被通知到。所以尽量使用notifyAll(),除非有十足的把握.

 

本文章参考极客时间中王宝令老师的Java并发编程实战课程,有兴趣的可以购买该课程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值