Java 如何确定ThreadPoolTaskExecutor池和队列大小?
这可能是一个更一般的问题,关于如何决定线程池大小,但是让我们使用SpringJava 如何确定ThreadPoolTaskExecutor池和队列大小?,java,spring,multithreading,threadpool,Java,Spring,Multithreading,Threadpool,这可能是一个更一般的问题,关于如何决定线程池大小,但是让我们使用SpringThreadPoolTaskExecutor来解决这个问题。对于池核心、最大大小和队列容量,我有以下配置。我已经阅读了所有这些配置的含义——有一个很好的答案 以上数字在我看来是随机的,我想了解如何根据我的环境正确设置它们。我将概述以下约束条件: 该应用程序将在一个双核CPU机箱上运行 执行者将执行一项通常需要1-2小时的任务 还有几秒钟就要结束了 通常我希望800个/分钟的任务提交给我的执行者,峰值为2500个/分钟 该
ThreadPoolTaskExecutor
来解决这个问题。对于池核心、最大大小和队列容量,我有以下配置。我已经阅读了所有这些配置的含义——有一个很好的答案
以上数字在我看来是随机的,我想了解如何根据我的环境正确设置它们。我将概述以下约束条件:
理想情况下,我想了解我需要考虑的其他约束条件,基于这些规则,我的池和队列大小将是一个合理的配置。 < P> Update:这个答案在过去几年中得到了一些选票,所以我给那些没有时间读我奇怪的隐喻的人添加了一个缩短的版本: TL;博士回答: 实际的限制是(逻辑)CPU核心只能同时运行单个线程。因此:
- 内核数量:CPU的逻辑内核数量*1/(执行任务时线程的可运行比率)
- 队列大小:尽可能多地等待
int cores=Runtime.getRuntime().availableProcessors()代码>
如果您试图将您的应用程序视为一个研讨会(实际研讨会):
- 处理者将由员工代表。它是为产品增加价值的物理单元
- 一项任务是一块原材料(加上一些说明清单)
- 你的线程是一张桌子,员工可以把任务放在上面工作
- 队列大小是将原材料运送到办公桌的传送带的长度
因此,你的问题变成了“在员工数量不变的情况下,我如何选择工厂内有多少张办公桌以及传送带的长度?”
关于多少张桌子(线)部分:
员工一次只能在一张办公桌上工作,每个办公桌上只能有一名员工。因此,基本的设置是至少有和员工一样多的办公桌(以避免任何员工(处理者)被遗漏而无法工作)
但是根据您的活动,您可以为每位员工提供更多的办公桌:
如果你的员工需要经常将邮件放入信封中,这需要他们全神贯注的操作(在编程中:分类收集、创建对象、增加计数器),拥有更多的办公桌不会有任何帮助,甚至可能是有害的,因为你的员工必须这样做
有时更换办公桌(切换上下文,这需要一些时间),从而离开他们正在处理的办公桌,在另一个办公桌上取得工作进展
但是,如果您的任务是制作陶器,并且依赖于您的员工在烤箱中等待粘土烹饪(了解如何访问外部资源,如文件系统、web服务等),那么您的员工可以在另一张桌子上制作粘土模型,稍后再回到第一张桌子
因此,只要您的任务的有效工作/等待比率(运行/等待)足够大,您就可以为每位员工提供更多的办公桌。办公桌的数量是指您的员工在等待时间内可以完成多少任务
对于传送带(队列)尺寸部件:
队列大小表示在开始拒绝任何其他任务(通过抛出异常)之前允许排队的项目数,因此是开始告诉“好的,我已经超额预订了,永远无法遵守”的阈值
首先,我要说的是,你的传送带需要安装在车间内。这意味着收集应该足够小,以防止内存不足错误(显然)
在那之后,它是基于你们公司的政策
@SpringBootApplication
@EnableAsync
public class MySpringBootApp {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MySpringBootApp.class, args);
}
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
return executor;
}
}