浅谈Java线程间通信之等待/通知

  

Java中的等待/通知/notifyAll可用来实现线程间通信,是对象类的方法,这三个方法都是土生土长的方法,是平台相关的,常用来实现生产者/消费者模式。先来我们来看下相关定义:

  

调用该方法的线程进入窟状态,只有等待另外线程的通知或中断才会返回,调用等()方法后,会释放对象的锁。

  

超时等待最多长的毫秒,如果没有通知就超时返回。

  

通知一个在对象上等待的线程,使其从等待()方法返回,而返回的前提是该线程获取到了对象的锁。

  

通知所有等待在该对象上的线程。

  

  

我们来模拟个简单的例子来说明,我们楼下有个小小的饺子馆,生意火爆,店里有一个厨师,一个服务员,为避免厨师每做好一份,服务员端出去一份,效率太低且浪费体力。现假设厨师每做好10份,服务员就用一个大木盘子端给客户,每天卖够100份就打烊收工,厨师服务员各自回家休息。

  

思考一下,要实现该功能,如果不使用等待/通知机制,那么最直接的方式可能就是,服务员隔一段时间去厨房看看,满10份就用盘子端出去。

  

  

1。如果服务员去厨房看的太勤,快服务员太累了,这样还不如每做一碗就端一碗给客人,大木盘子的作用就体现不出来了。具体表现在实现代码层面就是:需要不断的循环,浪费处理器资源。

  

2。如果服务员隔很久才去厨房看一下,就无法确保及时性了,可能厨师早都做够十份了,服务员却没观察到。

  

针对上面这个例子,使用等待/通知机制就合理的多了,厨师每做够10份,就喊一声“饺子好了,可以端走啦”。服务员收到通知,就去厨房将饺子端给客人;厨师还没做够,即还没收到厨师的通知,就可以稍微休息下,但也得竖起耳朵等候厨师的通知。

        包并发;      进口thread.BlockQueue;/* *   *由chengxiao>   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——饺子还没好,等待厨师通知…   cookThread——饺子好啦,厨师休息会儿   waiterThread——服务员把饺子端给客人了   waiterThread——打烊收工,服务员回家   cookThread——打烊收工,厨师回家      之前      

  

借用《并发编程的艺术》中的一张图来了解下等待/通知的运行机制

  

浅谈Java线程间通信之等待/通知

  

  

jvm为每一个对象和类都关联一个锁,锁住了一个对象,就是获得了对象相关联的监视器。

  

只有获取到对象锁,才能拿到监视器,如果获取锁失败了,那么线程就会进入阻塞队列中,如果成功拿到对象锁,也可以使用等()方法,在监视器上等,待此时会释放锁,并进入等地队列中。

  

关于锁和监视器的区别,有篇文章写得很详细透彻,在此引用一下,有兴趣的童鞋可以了解一下<强>详谈锁和监视器之间的区别_Java并发

  

  

1。首先,waitThread获取对象锁,然后调用等()方法,此时,等待线程会放弃对象锁,同时进入对象的等待队列WaitQueue中;

浅谈Java线程间通信之等待/通知