【问题标题】:What will happen when there are less threads than number of tasks for invokeAll()?当线程数少于 invokeAll() 的任务数时会发生什么?
【发布时间】:2018-12-06 00:18:52
【问题描述】:

我有以下代码:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                                                10, // corePoolSize
                                                10, // maximumPoolSize
                                                10, // keepAliveTime
                                                TimeUnit.SECONDS, 
                                                new LinkedBlockingQueue<>()
                                        );

final List<Callable<MyResponse>> tasks = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(concurrency);

for (int i = 0; i < 50; i++) {
    tasks.add(() -> {
        latch.countDown();
        latch.await();

        return getResponse(); // Returns a MyResponse object.
    });
}

final List<Future<ThrottleResponse>> futures = threadPoolExecutor.invokeAll(tasks);

有 50 个任务,但只有 10 个线程可用。根据我的测试结果,代码需要永远运行,我不明白。

invokeAll 方法会发生什么?这段代码中是否有死锁,为什么?我认为threadPoolExecutor 会将挂起的任务放在LinkedBlockingQueue 中并从队列中轮询以执行任务,所以应该没有死锁吧?

【问题讨论】:

  • 我想你已经回答了你自己的问题。
  • @shmosel 但我不明白为什么在这种情况下会出现死锁......
  • 因为线程数不够...
  • @shmosel 我认为threadPoolExecutor会将挂起的任务放入LinkedBlockingQueue并从队列中轮询执行任务,所以应该没有死锁吧?
  • 它会在完成之前的任务后轮询队列,但闩锁不会让它们完成,直到它们都开始。

标签: java concurrency java.util.concurrent


【解决方案1】:

执行器服务的正常行为是在池中每个可用的工作人员上启动一个任务,并将任何其他工作人员放入队列以等待工作人员可用。

您所做的是编写在所有其他任务开始之前无法完成的任务。由于您有 10 个工作人员,因此前 10 个任务每个都从一个工作人员开始......然后等待。前 10 个无法完成,因为它们正在等待其他任务开始,而其他任务无法启动,因为 executor 正在等待工作人员空闲......而且直到前 10 个中的一个才会发生任务完成。死锁。


你评论了:

我认为threadPoolExecutor会将挂起的任务放在LinkedBlockingQueue中并从队列中轮询执行任务,所以应该没有死锁吧?

所有任务都在正确排队。问题在于任务本身在排队后正在做什么。见上面的解释。


解决方案:

  • 不要将您的任务设计为等待其他任务开始。 (从您的示例中不清楚您为什么要这样做,但我怀疑它是否真的有必要。)

  • 如果您必须等待其他任务启动,请增加线程池大小,使其足以同时运行所有任务。

【讨论】:

    【解决方案2】:

    因为每个任务都在“latch.await();”上阻塞,LinkedBlockingQueue 中的排队任务将永远没有机会运行。这会造成僵局。您应该在每个任务中使用 latch.countDown()。但是主线程中的latch.await()。

    【讨论】:

      猜你喜欢
      • 2016-01-27
      • 1970-01-01
      • 2020-06-15
      • 2017-02-14
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多