admin管理员组文章数量:1574959
@Schedule创建的定时任务默认单线程的同步执行,虽然可以通过SchedulingConfigurer指定线程的个数,但是当代码运行起来时还是同步执行,同一个调度任务还需要阻塞等待上一次任务执行完成之后才能继续执行下一次任务。不同调度任务也是同一样的,需要阻塞等待上一个调度任务完成之后,才可以继续执行下一个调度任务。所以我们需要开始定时器的多线程异步执行。
1.Java多线程方式
通过在@Schedule注解方法,修改成异步执行,可以使用Java多线程
@SpringBootApplication
@Slf4j
@EnableScheduling
public class MyScheduledProgram {
public static void main(String[] args) {
SpringApplication.run(MyScheduledProgram.class, args);
}
/**
* 每两秒执行一次
*/
@Scheduled(fixedRate = 2000L)
public void myScheduledGet() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
log.info("++++++++++++MyScheduledGet");
});
}
ExecutorService executorServiceSet = Executors.newSingleThreadExecutor();
/**
* 每三秒执行一次
*
* @throws InterruptedException
*/
@Scheduled(fixedRate = 3000L)
public void myScheduledSet() {
executorServiceSet.submit(() -> {
int sleepTime = Double.valueOf(Math.random() * 10).intValue();
log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
try {
Thread.sleep(sleepTime * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
}
2.@EnableAsync和@Async
对于同一个调度任务的执行,如果任务的执行时间超过该任务的下一次执行时间,会启动另外一个线程去执行,不会跳造成任务丢失(前提:有空闲线程去执行)
对于多个不同的调度任务在执行时间上有交集,在执行任务A的过程中,到了任务B的执行时间,任务B不会阻塞,不需要等待任务A完成,会启动另外一个线程去执行任务B(前提:有空闲线程去执行)
@SpringBootApplication
@Slf4j
@EnableScheduling
@EnableAsync
public class MyScheduledProgram {
public static void main(String[] args) {
SpringApplication.run(MyScheduledProgram.class, args);
}
/**
* 每两秒执行一次
*/
@Scheduled(fixedRate = 2000L)
@Async("taskAsyncScheduler")
public void myScheduledGet() {
log.info("++++++++++++MyScheduledGet");
}
/**
* 每三秒执行一次
*
* @throws InterruptedException
*/
@Scheduled(fixedRate = 3000L)
// 指定值TaskScheduler使用默认
@Async("taskAsyncScheduler")
public void myScheduledSet() {
int sleepTime = Double.valueOf(Math.random() * 10).intValue();
log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
try {
Thread.sleep(sleepTime * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Bean("taskAsyncScheduler")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(3);
return taskScheduler;
}
}
3.注入TaskScheduler定时任务线程池,增加线程个数
@SpringBootApplication
@Slf4j
@EnableScheduling
public class MyScheduledProgram {
public static void main(String[] args) {
SpringApplication.run(MyScheduledProgram.class, args);
}
/**
* 每两秒执行一次
*/
@Scheduled(fixedRate = 2000L)
public void myScheduledGet() {
log.info("++++++++++++MyScheduledGet");
}
/**
* 每三秒执行一次
*
* @throws InterruptedException
*/
@Scheduled(fixedRate = 3000L)
public void myScheduledSet() {
int sleepTime = Double.valueOf(Math.random() * 10).intValue();
log.info("==============MyScheduledSet; sleep time(second):{}", sleepTime);
try {
Thread.sleep(sleepTime * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(3);
return taskScheduler;
}
}
本文标签: 多线程SpringBootschedule
版权声明:本文标题:SpringBoot @Schedule多线程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1725780210a1042165.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论