gpt4 book ai didi

java - 当 invokeAll() 的线程数少于任务数时会发生什么?

转载 作者:行者123 更新时间:2023-12-01 17:47:20 26 4
gpt4 key购买 nike

我有以下代码:

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 中,并从队列中轮询以执行任务,因此应该不会出现死锁,对吗?

最佳答案

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

您所做的就是编写一些任务,这些任务只有在所有其他任务开始后才能完成。由于您有 10 个工作人员,因此前 10 个任务各由一个工作人员启动......然后等待。前 10 个任务无法完成,因为它们正在等待其他任务启动,而其他任务无法启动,因为执行程序正在等待工作人员空闲......而直到前 10 个任务之一才会发生这种情况任务完成。死锁。

<小时/>

您评论过:

I think the threadPoolExecutor would put pending tasks in the LinkedBlockingQueue and poll from the queue to execute the tasks, so there should be no dead lock right?

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

<小时/>

解决方案:

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

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

关于java - 当 invokeAll() 的线程数少于任务数时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53642770/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com