我有一个进程,其中多个生成器填充从此队列检索的队列和单个使用者进程数据。
为了提高效率,消费者使用BlockingQueue#drainTo
API从队列中排出数据。但是有一个问题,当队列为空时,消费者会尝试在循环中耗尽数据,而不会消耗大量的CPU。
是否有API允许排除队列,其超时时间与BlockingQueue#poll(long timeout, TimeUnit unit)
类似?
消费者代码示例:
while (threadIsActive) {
List<Event> events = new ArrayList<>();
queue.drainTo(events);
processEvents(events);
}
答案 0 :(得分:0)
我最终使用了@Kayaman建议的poll / drainTo组合,我不太喜欢它,它看起来很难看。但我会接受提出更好解决方案的任何其他答案:
while (threadIsActive) {
Event firstEvent = queue.poll(queuePollTimeout, TimeUnit.MILLISECONDS);
if (firstEvent != null) {
// reserve enough space to fit first event, current queue capacity and
// new events which occur while we are draining
int drainCapacity = queue.size() * 2;
List<Event> events = new ArrayList<>(drainCapacity);
events.add(firstEvent);
queue.drainTo(events);
processEvents(events);
}
}
答案 1 :(得分:-1)
我同意@Kayaman,因为BlockingQueue#drainTo
API是非阻止API,因此在这种情况下,我们可以使用BlockingQueue#poll(long timeout, TimeUnit unit)
API来完成您的任务。也许你可以写下面的代码:
while (threadIsActive) {
List<Event> events = new ArrayList<>();
events.add(queue.poll(timeout, TimeUnit.SECONDS)) //Block until queue is EMPTY
queue.drainTo(events);
processEvents(events);
}