簡體   English   中英

Java中如何使用自動線程管理實現生產者/消費者

[英]How to use automatic thread management for implementing producer/consumer in Java

我需要實現一個生產者/消費者方案,消費者出於性能原因,嘗試在一批中處理許多工作項(每個工作項都排空工作隊列)。

目前,我只是創建固定數量的相同工作人員,它們在循環中的同一隊列上工作。 由於其中一些可能會死,我需要照顧更換它們。

我很想使用fixedThreadPool 來管理線程替換,但我的情況不是map 到Executor方案,因為生產者和消費者的所需粒度不匹配——只有消費者可以收集合適的一批工作。

當我的工作項不能表示為 Runnables/Callables 時,我有哪些管理(固定大小)線程池的選項?

(或者,我可以以某種方式保持我對批量生產的工作項的要求,並且仍然能夠使用 Executor 服務嗎?)

一種方法是讓生產者/消費者作為Runnable並使用BlockingQueue在它們之間傳遞任何數據。

例如,這里有一個簡單的生產者實現,它生成Stringqueue中的項目,以及批量讀取項目的消費者:

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);
    }
}

筆記:

我通過將實際工作項保存在 BlockingQueue 中解決了這個問題,但讓生產者向 Executor 提交通知任務,Executor 指示工作線程排空隊列。 當通知任務開始排隊時,一些工作人員將能夠從 BlockingQueue 中獲取多個工作項,而一些工作人員將一無所獲,這對於我的批處理目的來說已經足夠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM