【发布时间】:2013-04-22 18:58:12
【问题描述】:
我想了解take() 的工作原理,以及它是否适合“快速”消耗被推送到队列中的元素。
请注意,为了理解它的工作原理,我在这里没有考虑观察者模式:我知道我可以使用该模式对事件“快速做出反应”,但这不是我的问题所在。
例如,如果我有一个BlockingQueue(大部分是空的)和一个线程“卡住”等待一个元素被推送到该队列中以便可以使用它,那么有什么好方法可以最大限度地减少花费的时间(减少延迟)从元素被推入队列到被消耗之间?
例如,一个线程这样做有什么区别:
while( true ) {
elem = queue.peek();
if ( elem == null ) {
Thread.sleep( 25 ); // prevents busy-looping
} else {
... // do something here
}
}
另一个这样做的人:
while ( true ) {
elem = queue.take();
... // do something with elem here
}
(我认为是为了简化我们可以忽略在这里讨论异常的事情!?)
当您拨打take() 并且队列为空时,后台发生了什么? JVM 必须以某种方式让线程“休眠”,因为它不能一直忙于循环检查队列中是否有东西? take() 是否在后台使用了一些 CAS 操作?如果是这样,是什么决定了 take() 调用该 CAS 操作的频率?
如果有东西突然进入队列怎么办?该线程是如何在take() 上被阻塞的?以某种方式“通知”它应该立即采取行动?
最后,在应用程序的整个生命周期内,一个线程“卡”在 BlockingQueue 上的 take() 上是否“常见”?
这是一个与阻塞 take() 如何工作有关的大问题,我认为回答我的各种问题(至少是有意义的问题)将有助于我更好地理解这一切。
【问题讨论】:
标签: java multithreading concurrency queue blocking