我想了解它是如何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()如何工作有关的大问题,我认为回答我的各种问题(至少是一个有意义的问题)将帮助我更好地理解这一切。