Java 线程池 - 哪种类型,有多少?

Java threads pool - Which type and how many?

我有一个程序在多次迭代中运行。 在每个循环中,我启动了多达 3000 个并发线程,其中一些线程在迭代期间开始并在迭代结束前结束,其中一些线程处于启动状态并一直保持到迭代结束。

对于每次迭代,我都会重新创建线程。

  1. 我最好使用哪种类型的执行器:FixedThreadPool?线程池执行器?其他?
  2. 如果我需要设置线程值的数量 - 最大、最小、固定、任何其他... - 我应该如何确定它们?
  3. 我是否应该为每个线程提交创建一个新的 Future 对象以跟踪其状态?

谢谢

先回答你的问题,我一般用FixedThreadPool,最好的线程数一般是你机器的核心数(Runtime.getRuntime().availableProcessors())。

对于创建新的 Future 对象,这取决于;如果以后需要采集数据,当然需要Future来采集了?

作为扩展,我建议您查看 ForkJoinPool。这是一种旨在拆分工作并将结果重新组合在一起的任务。

3000 个并发线程对于目前的任何硬件来说都太高了。池的大小应反映硬件的能力(CPU 核心数)。您将需要尝试不同的大小以获得最佳结果,但是对于 3000 个并发线程,您只会让它们饿死。

你需要的是利用一个队列,你可以在循环中向队列添加任务,工作线程从队列中拉出并执行任务。工作线程将来自一个有限大小的线程池。

所以您肯定想要一个在给定队列上运行的 ThreadPoolExecutorjavadoc of the class 包含有关排队策略的有用信息。

好吧,关于线程数(min/max 等)的任何计算都不是那么简单,它需要了解您的工作负载和硬件。例如,如果您的任务完全 CPU 绑定,那么理论上最好的配置是线程数 = 内核数,而如果您的线程是 IO 绑定的(例如,调用数据库、网络等),那么这个数字将更大。您还需要考虑系统上的任何用户级别应用程序或默认 OS 进程 运行。另外 java 中的每个线程都有一个与之关联的堆栈内存,它将随着线程数的增加而累积。另一个因素是线程池任务队列的大小,它也会增加内存。最好的建议可能是 - 从可用内核数 Runtime.getRuntime().availableProcessors() 线程开始,然后进行分析。很可能你会到达一个数字,其中你的 performance/throughput 是最大的,然后随着线程数的进一步增加它下降。