[英]How to use automatic thread management for implementing producer/consumer in Java
我需要實現一個生產者/消費者方案,消費者出於性能原因,嘗試在一批中處理許多工作項(每個工作項都排空工作隊列)。
目前,我只是創建固定數量的相同工作人員,它們在循環中的同一隊列上工作。 由於其中一些可能會死,我需要照顧更換它們。
我很想使用fixedThreadPool 來管理線程替換,但我的情況不是map 到Executor
方案,因為生產者和消費者的所需粒度不匹配——只有消費者可以收集合適的一批工作。
當我的工作項不能表示為 Runnables/Callables 時,我有哪些管理(固定大小)線程池的選項?
(或者,我可以以某種方式保持我對批量生產的工作項的要求,並且仍然能夠使用 Executor 服務嗎?)
一種方法是讓生產者/消費者作為Runnable
並使用BlockingQueue
在它們之間傳遞任何數據。
例如,這里有一個簡單的生產者實現,它生成String
到queue
中的項目,以及批量讀取項目的消費者:
class ProducerConsumerPing {
private static final class PingProducer implements Runnable {
private final BlockingQueue<String> queue;
PingProducer(BlockingQueue<String> queue) {
this.queue = queue;
}
public void run() {
while (true) {
queue.offer("ping");
}
}
}
private static final class PingConsumer implements Runnable {
private final BlockingQueue<String> queue;
private final int batchSize;
PingConsumer(BlockingQueue<String> queue, int batchSize) {
this.queue = queue;
this.batchSize = batchSize;
}
public void run() {
while (true) {
List<String> batch = new ArrayList<>();
queue.drainTo(batch, batchSize);
System.out.println("Consumed: " + batch);
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService producers = Executors.newFixedThreadPool(10);
ExecutorService consumers = Executors.newFixedThreadPool(10);
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
for (int i = 0; i < 10; i++) {
producers.submit(new PingProducer(queue));
}
for (int i = 0; i < 10; i++) {
consumers.submit(new PingConsumer(queue, 10));
}
producers.shutdown();
producers.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
consumers.shutdown();
consumers.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
}
}
筆記:
在示例中,我使用String
作為work items
,但當然您可以將任何Object
放入隊列
消費者批處理是通過使用BlockingQueue.drainTo(Collection, int)實現的
我通過將實際工作項保存在 BlockingQueue 中解決了這個問題,但讓生產者向 Executor 提交通知任務,Executor 指示工作線程排空隊列。 當通知任務開始排隊時,一些工作人員將能夠從 BlockingQueue 中獲取多個工作項,而一些工作人員將一無所獲,這對於我的批處理目的來說已經足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.