千家信息网

java线程池如何合理设置最大线程数和核心线程数

发表于:2025-11-11 作者:千家信息网编辑
千家信息网最后更新 2025年11月11日,这篇文章将为大家详细讲解有关java线程池如何合理设置最大线程数和核心线程数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。线程池合理设置最大线程数和核心线程数工作中
千家信息网最后更新 2025年11月11日java线程池如何合理设置最大线程数和核心线程数

这篇文章将为大家详细讲解有关java线程池如何合理设置最大线程数和核心线程数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

线程池合理设置最大线程数和核心线程数

工作中有这样一个场景,需要处理千万级别的数据的一个算法,大部分是增删查的操作。这个时候就需要使用多线程去处理。

一开始是这么配置的

@Configuration@EnableAsync(proxyTargetClass = true)//利用@EnableAsync注解开启异步任务支持@ComponentScan({"com.ctfojt.auditbcarslogo.service"}) //必须加此注解扫描包public class ThreadPoolConfig implements AsyncConfigurer {    @Override    public Executor getAsyncExecutor() {        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();        taskExecutor.setCorePoolSize(10);//核心线程大小        taskExecutor.setMaxPoolSize(20);//最大线程大小        taskExecutor.setQueueCapacity(500);//队列最大容量        //当提交的任务个数大于QueueCapacity,就需要设置该参数,但spring提供的都不太满足业务场景,可以自定义一个,也可以注意不要超过QueueCapacity即可        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);        taskExecutor.setAwaitTerminationSeconds(10);        taskExecutor.setThreadNamePrefix("BCarLogo-Thread-");        taskExecutor.initialize();        return taskExecutor;    }}

这样配置效率很低,一天大概能处理30多万的数据。往后随着插入表的数据越来越多,处理速度也随之降低,跑个一两天之后,差不多能够处理10万多。完全满足不了需求。

后来网上查询线程池核心数配置

大部分都是这样的:

注:IO密集型(某大厂实践经验) 核心线程数 = CPU核数 / (1-阻塞系数)或着 CPU密集型:核心线程数 = CPU核数 + 1 IO密集型:核心线程数 = CPU核数 * 2

也尝试着这么配置,结果发现效率并不理想,提高不了多少。

最后我是这么配置的

结果效率大大提升,仅用不到一天的数据,就跑完了千万级的数据。

//获取当前机器的核数public static final int cpuNum = Runtime.getRuntime().availableProcessors();@Override    public Executor getAsyncExecutor() {        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();        taskExecutor.setCorePoolSize(cpuNum);//核心线程大小        taskExecutor.setMaxPoolSize(cpuNum * 2);//最大线程大小        taskExecutor.setQueueCapacity(500);//队列最大容量        //当提交的任务个数大于QueueCapacity,就需要设置该参数,但spring提供的都不太满足业务场景,可以自定义一个,也可以注意不要超过QueueCapacity即可        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);        taskExecutor.setAwaitTerminationSeconds(60);        taskExecutor.setThreadNamePrefix("BCarLogo-Thread-");        taskExecutor.initialize();        return taskExecutor;    }

完美的解决了问题!

线程池核心线程数与最大线程数的区别

线程池策略

corePoolSize:核心线程数;maximunPoolSize:最大线程数

每当有新的任务到线程池时,

  • 第一步:先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,且任务结束后将该线程保留在线程池中,不做销毁处理,若当前线程数量已达到corePoolSize,则进入下一步;

  • 第二步:判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中,满了则进入下一步;

  • 第三步:判断线程池中的线程数量是否达到了maxumunPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。注意: 在线程池中的线程数量超过corePoolSize时,每当有线程的空闲时间超过了keepAliveTime,这个线程就会被终止。直到线程池中线程的数量不大于corePoolSize为止。

(由第三步可知,在一般情况下,Java线程池中会长期保持corePoolSize个线程。)

饱和策略

当工作队列满且线程个数达到maximunPoolSize后所采取的策略

  • AbortPolicy:默认策略;新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。

  • CallerRunsPolicy:既不抛弃任务也不抛出异常,使用调用者所在线程运行新的任务。

  • DiscardPolicy:丢弃新的任务,且不抛出异常。

  • DiscardOldestPolicy:调用poll方法丢弃工作队列队头的任务,然后尝试提交新任务

  • 自定义策略:根据用户需要定制。

关于"java线程池如何合理设置最大线程数和核心线程数"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

线程 任务 核心 最大 处理 策略 工作 数据 数量 队列 配置 大小 核数 个数 场景 密集型 效率 篇文章 业务 参数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发部门年度工作总结问题 怀旧服服务器不能同步 我的世界服务器活跃值指令 设置远程访问服务器 开源服务器用什么处理器 西城区技术软件开发介绍 徐州市网络安全支队 网络安全实验分析与体会 宿城区多功能网络技术市场 易语言access 数据库 绍兴营销软件开发服务 现代移动网络技术 中国网络安全员有多少 浙江电脑服务器机箱采购 论文引用统计部数据库 街约网络技术工作室 海门无忧网络技术排名靠前 东莞手机软件开发热线 iphone查找网络安全性 敏哥化身服务器管理女神 网络安全法 执法协助 我的世界怎么在服务器里用小地图 长宁区企业网络技术咨询创新服务 更改默认数据库找不到新建的 网络安全加固的实施标准 网络安全进校园座谈会 软件开发犯罪案例 网络安全战略 方针 政策 河北润迪网络技术有限公司1 营造良好的网络安全氛围
0