SpringBoot Scheduled 定时任务
编辑
25
2025-01-06
默认情况下, SpringBoot Scheduled 是单线程执行定时任务的. 也就意味着, 如果一个任务执行时间较长, 线程会被阻塞. 如果此时有其他并发任务, 该任务将会被加入队列中排队处理, 直至有空闲线程来处理任务. 如果解决方案就是, 让 SpringBoot Scheduled 可以多线程执行定时任务.
配置线程池
1. 配置文件
默认情况下, 线程池数量是 1, 可以使用配置文件修改默认的线程池数量.
注意事项:
如果在配置文件设置了虚拟线程, 该参数将失效. 相关信息可以查看 TaskSchedulingProperties 中 Pool 的逻辑.
因为每个任务都会占用一个线程池数量, 若任务执行时间较长, 线程池数量被耗尽, 同样会出现没有空闲线程来处理任务的情况. 可以通过 @Async 等异步任务执行实际任务逻辑.
application.yml 示例:
spring:
task:
scheduling:
pool:
size: 8
2. 实现 SchedulingConfigurer 接口
通过实现 SchedulingConfigurer 接口来自定义线程池配置, 是否开启虚拟线程不会影响定时任务的配置.
注意事项:
因为每个任务都会占用一个线程池数量, 若任务执行时间较长, 线程池数量被耗尽, 同样会出现没有空闲线程来处理任务的情况. 可以通过
@Async
等异步任务执行实际任务逻辑.
/**
* 定时任务配置
*
* @author Toint
* @date 2024/11/9
*/
@EnableScheduling
@Configuration
@Slf4j
public class ScheduledConfig implements SchedulingConfigurer {
/**
* 设置任务线程池
*/
@Override
public void configureTasks(@NonNull ScheduledTaskRegistrar taskRegistrar) {
Assert.notNull(taskRegistrar, "taskRegistrar must not be null");
final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setVirtualThreads(true); // 使用虚拟线程执行任务
threadPoolTaskScheduler.setPoolSize(RuntimeUtil.getProcessorCount() * 2); // 线程池数量为当前硬件核心数量的2倍
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); // 等待所有任务完成再关闭线程池
threadPoolTaskScheduler.setAwaitTerminationSeconds(60); // 等待线程池终止的最长时间(秒)
threadPoolTaskScheduler.initialize(); // 初始化
}
}
- 0
- 0
-
分享