2016-11-07 76 views
0

我有一個進程,其中多個生產者填充隊列和單個使用者進程從其隊列中檢索的數據。帶有超時的排水隊列

爲了提高效率消費者從隊列中使用BlockingQueue#drainTo API排出數據。但有一個問題,當隊列爲空時,消費者會嘗試在循環中耗盡數據,而不會延遲消耗大量CPU。

是否有API允許排隊隊列超時類似於BlockingQueue#poll(long timeout, TimeUnit unit)

示例代碼消費:

while (threadIsActive) { 
    List<Event> events = new ArrayList<>(); 
    queue.drainTo(events); 
    processEvents(events); 
} 
+0

因此,您的方法最終導致性能惡化。 – Kayaman

+0

並非如此,大部分時間隊列不是空的,並且這種方法改善了高負載時段處理。現在我想在系統不負載時提高CPU消耗。 – hoaz

+0

然後在隊列爲空時執行'poll()'。 – Kayaman

回答

0

我結束了使用輪詢/組合的drainTo這是由@Kayaman建議,我不很喜歡,它看起來醜陋。但我會接受其他答案,提出更好的解決方案:

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

我同意@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); 
    }