Springboot定时任务【多线程处理】
对于服务端同时开启多个定时任务的需求,按照普通的操作方式,springboot单线程的处理方式会造成许多问题,比如两个定时任务时间冲突,只能等一个执行完成在执行另一个;当一个定时任务出现问题,另一个定时任务也无法执行,整个定时任务服务可能会卡死,不再运行,下面所以写,通过多线程方式调用定时任务,创建线程池,姐可能的避免任务冲突的情况;第一步,创建线程池package com.**.config;i
·
对于服务端同时开启多个定时任务的需求,按照普通的操作方式,springboot单线程的处理方式会造成许多问题,比如两个定时任务时间冲突,只能等一个执行完成在执行另一个;当一个定时任务出现问题,另一个定时任务也无法执行,整个定时任务服务可能会卡死,不再运行。下面所写,通过多线程方式调用定时任务,创建线程池,即可避免任务冲突的情况;
第一步,创建线程池
package com.**.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @ProjectName: tshare_blsj_server
* @Package: com.**.config
* @ClassName: TaskPoolConfig
* @author:
* @description: 线程池配置
* @date:
* @version: 1.0
*/
@EnableAsync
@Configuration
public class TaskPoolConfig {
@Bean("tbsjTaskExecutor")
public Executor mailNumPoolSingleTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//设置为1,任务顺序执行
executor.setCorePoolSize(10);//核心线程数:线程池创建时候初始化的线程数
executor.setMaxPoolSize(100);//最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setQueueCapacity(20);//缓冲队列200:缓冲执行任务的队列
executor.setKeepAliveSeconds(60);//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setThreadNamePrefix("tbsjTaskExecutor-");//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());// 线程池对拒绝任务的处理策略
return executor;
}
@Bean("otherSingleTaskExecutor")
public Executor otherSingleTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//设置为1,任务顺序执行
executor.setCorePoolSize(1);//核心线程数:线程池创建时候初始化的线程数
executor.setMaxPoolSize(1);//最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setQueueCapacity(20);//缓冲队列200:缓冲执行任务的队列
executor.setKeepAliveSeconds(60);//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setThreadNamePrefix("otherSingleTaskExecutor-");//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());// 线程池对拒绝任务的处理策略
return executor;
}
}
第二步:定时任务加注解
package com.**.task;
import com.**.service.StationInfoService;
import com.**.service.TshareStationData2Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
/**
* @ProjectName: tshare_blsj_server
* @Package: com.**.task
* @ClassName: Data2NowExceptionTask
* @author:
* @description:
* @date:
* @version: 1.0
*/
@Slf4j
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
@EnableAsync
public class Data2NowExceptionTask {
@Autowired
private StationInfoService stationInfoService;
@Autowired
private TshareStationData2Service tshareStationData2Service;
@Scheduled(cron = "0/10 * * * * *")
@Async("tbsjTaskExecutor") // 通过注解指定使用的线程池
public void det(){
log.info("Scheduled task is running... ...");
}
}
控制台打印,定时任务执行,可以看到,每次都是不同线程:
当核心线程(10个)都用完之后,第一个线程所在的定时任务已经执行完成,那么,下一个定时任务将继续使用核心线程池中的第一个线程!
当核心线程(10个)都用完之后,第一个线程所在的定时任务尚未执行完成,将开启新的线程去执行定时任务,直到前面有任务执行完成,下个任务才会使用之前的线程去执行;
更多推荐
所有评论(0)