使用ThreadPoolExecutor作为队列有什么缺点?

时间:2016-08-09 09:46:34

标签: java executorservice java.util.concurrent

对于传统的Producer-Consumer问题,我们可以使用ExecutorService作为队列。有什么缺点呢?效率低下吗?因为线程的创建成本很高。

executor = Executors.newFixedThreadPool(90);
// This will be called many times concurrently
public void processObjectsWithFixedSetOfThreads(Foo objectToProcess) {
   //Create a new thread and submit (executor is of fixed size hence extra tasks will be queued)
   executor.submit(new ObjectProcessorWorker(objectToProcess));
}

class ObjectProcessorWorker implements Runnable() {
  public ObjectProcessorWorker(Foo obj) {
     this.obj = obj;
  }

  public void run() {
     longRunningProcess(obj);
  }

}

为什么{@ 3}}建议用于生产者 - 消费者问题但是也可以BlockingQueue完成(如上所示)?

修改

许多人没有得到差异,因为ThreadPoolExecutor在内部维护了BlockingQueue。

在饼干工厂,有一个包装饼干的任务。如果我是它的拥有者,我有两种方法来加快包装任务。

  1. 在装配线上放置饼干和包装纸,有10名工人在做包装工作。

    我 - > queue.put(biscuits, wrapper)

    工人 - > queue.take()

  2. 创建一个包裹饼干的任务,将它放在装配线上,然后让10名工人完成。

    我 - > new Task(biscuits, wrapper)

    工人 - > task = queue.take(); do(task);

  3. 我问的是后者的缺点。

2 个答案:

答案 0 :(得分:1)

每当你定义ThreadPoolExecutore ..如下所示

ExecutorService threadPoolExecutor =
        new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>()
                );

如果在将某个任务委托给线程池时在线程池中创建了少于 corePoolSize 线程,则会创建一个新线程,即使池中存在空闲线程也是如此。

如果任务的内部队列已满,并且正在运行corePoolSize或更多线程,但运行的线程少于 maximumPoolSize ,则会创建一个新线程来执行任务

现在,如果您已经定义阻塞队列 ...而不是 corePoolSize 之后,它会将新线程添加到队列中......直到达到队列容量。 在溢出队列之后,它将生成新的线程,直到 maximumPoolSize

不知道将ExecutorService用作队列有什么不利之处。我不认为有任何不利之处。

答案 1 :(得分:0)

使用Executors.newFixedThreadPool(int)创建ThreadPoolExecutor时,您正在创建BlockingQueue

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

因此,你没有这样做&#34;没有&#34;如果您以这种方式创建的线程池,则为阻塞队列;它只是对你隐藏。