java线程池合理设置最大线程数和核心线程数方式
作者:李振伟 发布时间:2021-06-19 22:02:31
线程池合理设置最大线程数和核心线程数
工作中有这样一个场景,需要处理千万级别的数据的一个算法,大部分是增删查的操作。这个时候就需要使用多线程去处理。
一开始是这么配置的
@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方法丢弃工作队列队头的任务,然后尝试提交新任务自定义策略
:根据用户需要定制。
来源:https://blog.csdn.net/lifulian318/article/details/109000675
猜你喜欢
- 1. eclipse的git插件安装与配置1.1 git插件安装新版本的eclipse已经自带了GIt了,就不用安装了。老版本的eclips
- 基于jsr303 通过自定义注解实现,实现思路:存在一些瑕疵,后续补充完善。加入依赖部分版本已不默认自动引入该依赖,选择手动引入<de
- HttpServletRequest介绍HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HT
- 在使用SpringBoot做接口访问如何做接口的限流,这里我们可以使用google的Guava包来实现,当然我们也可以自己实现限流,Guav
- 本文实例讲述了Java高级特性之反射机制。分享给大家供大家参考,具体如下:老规矩我们还是先提出几个问题,一门技术必然要能解决一定的问题,才有
- 1、Alt+*(按钮快捷键)按钮快捷键也为最常用快捷键,其设置也故为简单。在大家给button、label、menuStrip等其他控件的T
- 这篇文章主要介绍了springboot全局异常处理代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- java 中二分法查找的应用实例二分查找的前提是:数组有序 注意:mid的动态变化,否则出错!!! 实例代码:publ
- 本文实例讲述了Android开发中使用颜色矩阵改变图片颜色,透明度及亮度的方法。分享给大家供大家参考,具体如下:一、如图二、代码实现publ
- Java的super关键字当子类重写父类的方法后,子类对象将无法直接访问父类被重写的方法。为了解决这个问题,在Java中专门提供了一个sup
- 服务器端我们用软件模拟,是一个很小巧的软件,下载软件NetAssist:http://xiazai.jb51.net/201403/tool
- 最近在学ssh,一直搞不懂$,%,#的区别,做了点小练习,慢慢也懂了一点,将自己所学的也记录下来吧。 存在一下一个实
- 问题原因Springboot get请求是参数过长抛出异常:Request header is too large 的问题错误描述java.
- public final class Integer extends Number implements Comparable<Int
- EntityWrapper的常用方法#WHERE (issue_type = ?) AND (status = ? OR status =
- 这篇文章主要介绍了Java String的intern用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- Mybatis的Dao层实现传统开发方式1、编写UserDao接口public interface UserMapper {public L
- 目录一,功能二,工具三、效果图:四、数据库设计五、JAVA层次分析六、主要Java代码分析一,功能管理员登录图书借阅信息管理图书信息管理管理
- 最近项目用到txt文件和xls文件的转换,这里记录一下具体的思路。下面利用java代码实现txt转xls,这里要使用到jxl.jar包,这个
- 自定义转换器实现参数去空格1.自定义转换器类实现Converter<S, T>类,重写convert()方法,直接上代码。/**