Joe*_*tov 9 java concurrency blockingqueue
考虑一个BlockingQueue和几个线程等待poll(long, TimeUnit)(可能还在上take()).
现在队列是空的,并且希望通知等待的线程他们可以停止等待.预期的行为是null返回或声明InterruptedException抛出.
Object.notify()LinkedBlockingQueue因为线程正在等待内部锁定而无法工作.
有任何直截了当的方式吗?
unb*_*eli 13
BlockingQueue的Javadoc提出了一个好方法:
BlockingQueue本质上不支持任何类型的"关闭"或"关闭"操作,以指示不再添加任何项目.这些功能的需求和使用倾向于依赖于实现.例如,一种常见的策略是生产者插入特殊的流末端或毒物对象,这些对象在被消费者采用时会相应地进行解释.
传统的方法是中断线程,但这当然要求它们正确处理中断.
这意味着InterruptedException在阻塞方法周围正确捕获和处理s,并interrupted定期检查(并采取行动)该标志.
API或语言规范中没有任何内容将中断与任何特定的取消语义联系起来,但在实践中,除了取消之外使用中断是脆弱的并且难以在较大的应用程序中维持.[...]
中断通常是实施取消的最明智的方式.
在7.1.1节中说Java Concurrency in Practice.正确处理中断的一个例子(这是生产者线程,而不是消费者,但在当前上下文中这种差异可以忽略不计):
class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是将超时参数设置得poll相当低,以便线程定期唤醒并且可以足够快地注意到中断.我仍然认为根据您的特定线程取消策略明确处理InterruptedException始终是一个好习惯.
| 归档时间: |
|
| 查看次数: |
7579 次 |
| 最近记录: |