1.原因
@Schedule定时任务和异步注解@Async使用的默认线程池时, 池中允许的最大线程数和最大任务等待队列都是Integer.MAX_VALUE
.
2.解决
2.1、可以手动异步编排,交给某个线程池来执行。
首先我们先向Spring中注入一个我们自己编写的线程池,参数自己设置即可,我这里比较随意。
@Configuration public class MyTheadPoolConfig { @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //设置核心线程数 executor.setCorePoolSize(10); //设置最大线程数 executor.setMaxPoolSize(20); //缓冲队列200:用来缓冲执行任务的队列 executor.setQueueCapacity(200); //线程活路时间 60 秒 executor.setKeepAliveSeconds(60); //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池 // 这里我继续沿用 scheduling 默认的线程名前缀 executor.setThreadNamePrefix("nzc-create-scheduling-"); //设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.setWaitForTasksToCompleteOnShutdown(true); return executor; } }
然后在定时任务这里注入进去:
@Slf4j @Component @EnableScheduling public class ScheduleService { @Autowired TaskExecutor taskExecutor; @Scheduled(cron = "0/5 * * * * ? ") public void testSchedule() { CompletableFuture.runAsync(()->{ try { Thread.sleep(10000); log.info("当前执行任务的线程号ID===>{}", Thread.currentThread().getId()); } catch (Exception e) { e.printStackTrace(); } },taskExecutor); } }
2.2、将定时任务加上异步注解@Async
,将其改为异步的定时任务,另外自定义一个系统通用的线程池,让异步任务使用该线程执行任务~
异步定时任务其实和上面的方式原理是一样的,不过实现稍稍不同罢了。
在定时任务的类上再加一个@EnableAsync
注解,给方法添加一个@Async
即可。
不过一般@Async都会指定线程池,比如写成这样@Async(value = "taskExecutor")
,
@Slf4j @Component @EnableAsync @EnableScheduling public class ScheduleService { @Autowired TaskExecutor taskExecutor; @Async(value = "taskExecutor") @Scheduled(cron = "0/5 * * * * ? ") public void testSchedule() { try { Thread.sleep(10000); log.info("当前执行任务的线程号ID===>{}", Thread.currentThread().getId()); } catch (Exception e) { e.printStackTrace(); } } }
标签:异步,自定义,Schedule,任务,线程,executor,Async,public From: https://www.cnblogs.com/jiutang001/p/18329474