Spring Boot中配置定时任务、线程池与多线程池执行的方法
作者:Half 发布时间:2021-08-08 13:31:30
配置基础的定时任务
最基本的配置方法,而且这样配置定时任务是单线程串行执行的,也就是说每次只能有一个定时任务可以执行,可以试着声明两个方法,在方法内写一个死循环,会发现一直卡在一个任务上不动,另一个也没有执行。
1、启动类
添加@EnableScheduling开启对定时任务的支持
@EnableScheduling
@SpringBootApplication
public class TestScheduledApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
public static void main(String[] args) {
new SpringApplicationBuilder(TestScheduledApplication.class).web(true).run(args);
}
}
2、配置执行定时任务的类
添加@Component扫描本类,在方法上添加@Scheduled注解声明定时任务,配置时间周期
@Component
public class TestTask1 {
private static final Logger logger = LogManager.getLogger();
// 间隔1秒执行一次
@Scheduled(cron = "0/1 * * * * ?")
public void method1() {
logger.info("——————————method1 start——————————");
logger.info("——————————method1 end——————————");
}
}
配置线程池执行定时任务
因为有时候需要执行的定时任务会很多,如果是串行执行会带来一些问题,比如一个很耗时的任务阻塞住了,一些需要短周期循环执行的任务也会卡住,所以可以配置一个线程池来并行执行定时任务
1、配置线程池
添加@EnableAsync开启对异步的支持
@Configuration
@EnableAsync
public class ExecutorConfig {
@Bean
public Executor executor1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("test-schedule2-");
executor.setMaxPoolSize(20);
executor.setCorePoolSize(15);
executor.setQueueCapacity(0);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
2、配置定时任务异步执行
添加@Async注解,表示该定时任务是异步执行的,因为上面线程池配置了名字,所以可以看到打印的日志是该线程池中的线程在执行任务,如果没有配置线程池的话会默认使用SimpleAsyncTaskExecutor,这个异步执行器每次都会开启一个子线程执行,性能消耗比较大,所以最好是自己配置线程池
@Async
@Scheduled(cron = "0/1 * * * * ?")
public void method1() {
logger.info("——————————method1 start——————————");
logger.info("——————————method1 end——————————");
}
配置多个线程池分别执行不同的定时任务
因为有些定时任务是比较重要的,有些则是不太重要的,想把定时任务分别放到不同的线程池中,也是可以实现的。
1、配置多个线程池
分别配置两个线程池
@Configuration
@EnableAsync
public class ExecutorConfig1 {
@Bean
public Executor executor1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("test-schedule1-");
executor.setMaxPoolSize(20);
executor.setCorePoolSize(15);
executor.setQueueCapacity(0);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
@Bean
public Executor executor2() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("test-schedule2-");
executor.setMaxPoolSize(20);
executor.setCorePoolSize(15);
executor.setQueueCapacity(0);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
2、定时任务显示指定调用线程池
因为上面在配置类里面初始化了两个线程池,所以会有两个线程池分别叫executor1和executor1被生成放到容器中,因为@Bean注解生成的对象默认就是和方法名相同的名字,而@Async注解是可以指定使用哪个线程池的。这样就可以在不同的线程池中执行不同的定时任务了
// 间隔1秒执行一次
@Async("executor1")
@Scheduled(cron = "0/1 * * * * ?")
public void method1() {
logger.info("——————————method1 start——————————");
logger.info("——————————method1 end——————————");
}
// 间隔1秒执行一次
@Scheduled(cron = "0/1 * * * * ?")
@Async("executor2")
public void method2() {
logger.info("——————————method2 start——————————");
logger.info("——————————method2 end——————————");
}
注意:
没有配置自己的线程池时,会默认使用SimpleAsyncTaskExecutor。
如果项目中只配置了一个线程池,那么不需要显示指定使用这个线程池,spring也会自动使用用户配置的线程池,但是如果配置了多个就必须要显示指定,否则还是会使用默认的。
如果想要指定使用哪个线程池,可以使用@Async("executor2")显示指定。
来源:https://segmentfault.com/a/1190000020299913
猜你喜欢
- 之前在开发一个程序,希望能够通过属性名称读取出属性值,但是由于那时候不熟悉反射,所以并没有找到合适的方法,做了不少的重复性工作啊!然后今天我
- 在C# winform 应用程序中,对于键盘响应事件,经常使用到"KeyPress"、“KeyUp”、"Key
- 准备工作HALCON示例程序的描述部分一直是英文的,看起来很不方便。我决定汉化一下HALCON示例程序的描述,准备工作如下:拿到HALCON
- 开发项目的时候,表很多,是不可能一点点的自己去写xml ,dao文件的,这里就需要用到代码的自动生成工具了。第一步:导入jar包,当然,这之
- ArrayBlockingQueue介绍ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列。线程安全是指,ArrayB
- java 中HttpClient传输xml字符串实例详解介绍:我现在有一个对象page,需要将page对象转换为xml格式并以binary方
- 本文实例讲述了C#执行SQL事务用法。分享给大家供大家参考。具体分析如下:1.通过存储过程。2.通过C#中提供的Transaction。这里
- 算法文章,总是带给我们无穷的思考和兴趣,一个问题,多种解决方法,看你如何去思考它,对于标题所引出的问题,我觉得,使用递归是比较有效的方法,当
- 上一次自己写了一个多线程断点续传下载的demo,过于麻烦,bug超多,所以我学习使用xutils来完成此功能。先将xutils依赖搭建好(上
- 本文讲述了Android应用程序模型之应用程序,任务,进程,线程。分享给大家供大家参考,具体如下:大多数操作系统,在应用程序所寄存的可执行程
- c#调用surfer软件,添加应用的方法:1.在项目文件上右键->添加引用2.选择COM标签页3.找到Surfer 9 type li
- 直接插入排序<code class="language-java hljs ">import java.ut
- this在Java中,this的作用和其词义很接近。它在方法内部使用,即这个方法所属对象的引用;它在构造器内部使用,表示该构造器正在初始化的
- 在使用spring框架中我们都知道,某个类如果使用了@Service、@Autowire 这种依赖注入的方式引用了其他对象,在另外一个类中,
- CSV(Comma Separated Values)文件是一种纯文本文件,包含用逗号分隔的数据,常用于将数据从一个应用程序导入或导出到另一
- SpringBoot整合第三方技术一、整合Junit新建一个SpringBoot项目使用@SpringBootTest标签在test测试包内
- 实例如下所示:/** * 创建多级目录文件 * * @param path 文件路径 * @throws IOException */pri
- 话不多说,请看代码:public FileResult GetExcelFile() {  
- 在做商城的项目中,有这么个需求,就是一个产品下有两个价格,一个是市场价,一个是销售价,这时要把市场价添加个删除线;刚开始遇到这个时,在网上找
- ModbusModbus是一种串行通信协议。Modbus 一个工业上常用的通讯协议、一种通讯约定。Modbus协议包括RTU、ASCII、T