我想知道我对生产者消费者设计的理解是否正确,方法是使用ExecutorService&ArrayBlockingQueue。我了解实现此设计的方法有很多,但我想最后取决于问题本身。

我必须面对的问题是:我有一个制作人,可以读取一个大文件(6GB);它逐行读取并将每一行转换为一个对象。它将对象放置在ArrayBlockingQueue中。

使用者(很少)从ArrayBlockingQueue中获取对象并将其持久保存到数据库中。

现在,显然生产者比消费者快得多;将每一行转换为一个对象要花费几分之一秒的时间,但对于消费者来说则需要更长的时间。

因此...如果我希望通过执行此操作来加快此过程的速度:我创建了两个分类为'ProducerThread'和'ConsumerThread'的类,它们共享ArrayBlockingQueue。在2之间协调的线程如下所示:

@Override
public void run()
{
    try{

        ArrayBlockingQueue<Ticket> queue = new ArrayBlockingQueue<Ticket>(40);
        ExecutorService threadPool = Executors.newFixedThreadPool(8);

        threadPool.execute(new SaleConsumerThread("NEW YORK", queue));
        threadPool.execute(new SaleConsumerThread("PARIS", queue));
        threadPool.execute(new SaleConsumerThread("TEL AVIV", queue));
        threadPool.execute(new SaleConsumerThread("HONG KONG", queue));
        threadPool.execute(new SaleConsumerThread("LONDON", queue));
        threadPool.execute(new SaleConsumerThread("BERLIN", queue));
        threadPool.execute(new SaleConsumerThread("AMSTERDAM", queue));

        Future producerStatus = threadPool.submit(new SaleProducerThread(progressBar, file, queue));
        producerStatus.get();
        threadPool.shutdown();

    }catch(Exception exp)
    {
        exp.printStackTrace();
    }
}

我的问题是:
  • 上面的设计是否会实际上同时使用每个线程以及?我的电脑是两个2.4GHz四核。
  • 我不确定Future和.get()是做什么用的?

  • 顺便说一下,结果很快(考虑到第一个版本是连续的,花费了3个小时),现在大约需要40分钟(但可能还有改进的余地)。

    谢谢你的指导

    最佳答案

    我将看看等待IO花费了多少时间,以及在CPU中花费了多少时间。我怀疑您的主要瓶颈是数据库,您需要研究如何提高导入效率。您可以尝试分批更新,因为这可以提高吞吐量。

    关于java - 生产者使用者-ExecutorService和ArrayBlockingQueue,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10392855/

    10-10 13:38