首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

生产者消费者[容易示例]

2012-08-27 
生产者消费者[简单示例]??Restaurant是WaitPerson和Chef的焦点, 他们都必须子回到在为哪个Restaurant工作,

生产者消费者[简单示例]

?

?

Restaurant是WaitPerson和Chef的焦点, 他们都必须子回到在为哪个Restaurant工作,

因为他们必须和这家饭店的“餐窗”打交道, 以便放置或拿取restaurant.meal。 在run()

中, WiatPerson进入wait()模式, 停止其任务, 直到被Chef的notifyAll()唤醒。

?

由于这是一个非常简单的程序,因此我们直到只有一个任务将在WaitPerson的锁上

等待,即WaitPerson任务自身。 出于这个原因, 理论上可以调用notify()而不是

notifyAll()。 但是,在更复杂的情况下,可能会有多个任务在某个特定对象上

等待,因此就不知道哪个任务应该被唤醒,因此,调用notifyAll()更安全些,

这样可以唤醒等待这个锁的所有任务, 而每个任务都必须决定这个通知是否与

自己相关。

?

注意, wait()被包装在一个while()语句中, 这个语句在不断地测试正在等待的食物。

看上去有点怪-- 如果在等待一个订单,一旦被唤醒,这个订单就必须是可获得的,对嘛?

正如前面注意到的, 问题是在并发应用中, 某个洽谈的任务可能会在WaitPerson被唤醒,

会突然插足拿走订单,唯一安全的方式是使用下面这种wait()的惯用法

while(conditionIsNotMet)

wait();

?

对notifyAll()的调用必须首先捕获waitPerson上的锁, 而在WatiPerson.run()中

的对wati()的调用会自动地释放这个锁, 因此这是有可能实现的。 因为调用

notifyAll()必然拥有这个锁, 所以这保证两个试图在统一个对象上调用notifyAll()

的任务不会相互冲突。

?

通过把整个run()方法体放到一个try语句块中, 可使得这2个run()方法都被设计为

可以有序地关闭。 catch自居将紧挨着run()方法的结束括号之前结束,因此,如果这个任务

收到了InterruptedException异常, 它将在捕获异常之后立即结束。

?

注意, 在Chef中, 在调用shutdownNow()之后, 应该直接从run()中返回,并且通常这就是

你应该做的。 但是,以这种方式执行还有一些更有趣的东西。 shutdownNow()将向所有

由ExecutorService启动的任务发送interrupt(), 但是在Chef中,任务并没有获得该

interrupt()之后立即关闭, 因为当任务试图进入一个(可中断的)阻塞操作时,这个

中断只能抛出InterruptedException。 因此, 将看到首先显示了 "Order up!",然后

当Chef试图调用Slee()时, 抛出了InterruptedException. 如果移除对slee()的调用,

那么这个任务将回到run()循环的顶部,并由于Thread.interrupted()测试而退出,

同时并不抛出异常。


热点排行