首页 文章

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

提问于
浏览
-1

对于传统的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);
  }

}

为什么BlockingQueue被推荐用于 生产环境 者 - 消费者问题但是它也可以完成without that(如上所示)?

编辑

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

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

  • 在装配线上放置 Cookies 和包装纸,有10名 Worker 正在做包装工作 .

我 - > queue.put(biscuits, wrapper)

Worker - > queue.take()

  • 创建一个包裹 Cookies 的任务,将它放在装配线上,让10名 Worker 做到这一点 .

我 - > new Task(biscuits, wrapper)

Worker - > task = queue.take(); do(task);

我问的是后者的缺点 .

2 回答

  • 1

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

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

    如果在将任务委托给线程池时在线程池中创建的线程少于 corePoolSize ,则即使池中存在空闲线程,也会创建新线程 .

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

    现在,如果你定义了 blocking queue ...而不是 corePoolSize 之后,它会将新线程添加到队列中......直到达到队列容量 . 在溢出 queue 之后,它将生成新的线程 maximumPoolSize .

    不知道使用ExecutorService作为队列有什么不利之处 . 我不认为有任何缺点 .

  • 0

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

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

    因此,如果你以这种方式创建一个线程池,你就不会“没有”阻塞队列 . 它只是对你隐藏 .

相关问题