一、什么是定时任务
-
第1种是基于注解的方式,比较常用,但是这种在程序运行过程种不能动态更改定时任务的时间。 -
第2种是可以动态更改定时任务的时间。 -
第3种是可以动态更改定时任务的时间,还可以动态启动,停止定时任务。
一、代码示例
@Scheduled 定时任务
package com.chenpi.springschedule.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author
* @version 1.0
* @description 定时任务类
* @date 2021/3/2
*/
@Component
public class ScheduledTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTask.class);
// 每5秒执行一次
@Scheduled(cron = "0/5 * * * * ? ")
public void test() {
LOGGER.info(">>>>> ScheduledTask doing ...");
}
}
然后在启动类上添加@EnableScheduling
注解开启定时任务。默认情况下,系统会自动启动一个线程,调度执行项目中定义的所有定时任务。
package com.chenpi.springschedule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
启动项目,即可在控制台中每5秒看到定时任务被执行
2022-04-11 20:46:55.011 INFO 11800 --- [ scheduling-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 20:47:00.014 INFO 11800 --- [ scheduling-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 20:47:05.003 INFO 11800 --- [ scheduling-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 20:47:10.003 INFO 11800 --- [ scheduling-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 20:47:15.001 INFO 11800 --- [ scheduling-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
多线程定时任务
使用@Scheduled
注解形式的定时任务,默认是单个线程来执行项目中的所有定时任务的。即使如果同一时刻有两个定时任务需要执行,那么也只能其中一个定时任务完成之后再执行下一个定时任务。如果项目只有一个定时任务还好。如果定时任务增多时,如果一个任务被阻塞,则会导致其他任务无法正常执行。
可以配置任务调度线程池,来解决以上问题。首先配置一个线程池,如下所示:
package com.chenpi.springschedule.config;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* @author
* @version 1.0
* @description 线程池配置
* @date 2021/3/2
*/
@Configuration
public class ExecutorConfig {
public static final int CORE_POOL_SIZE = 2;
public static final int MAX_POOL_SIZE = 8;
public static final int QUEUE_CAPACITY = 100;
@Bean("myExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数大小
executor.setCorePoolSize(CORE_POOL_SIZE);
// 最大线程数大小
executor.setMaxPoolSize(MAX_POOL_SIZE);
// 阻塞队列容量
executor.setQueueCapacity(QUEUE_CAPACITY);
// 线程名前缀
executor.setThreadNamePrefix("myTask-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
然后通过@Async
注解添加到定时任务方法上
package com.chenpi.springschedule.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author
* @version 1.0
* @description 定时任务类
* @date 2021/3/2
*/
@Component
public class ScheduledTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTask.class);
@Scheduled(fixedRate = 1000)
@Async("myExecutor")
public void test() {
try {
// 休眠5秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info(">>>>> ScheduledTask doing ...");
}
@Scheduled(fixedRate = 1000)
@Async("myExecutor")
public void test01() {
try {
// 休眠5秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info(">>>>> ScheduledTask01 doing ...");
}
}
终输出结果如下,发现多个定时任务是由线程池中的不同线程来执行了。
2022-04-11 22:00:44.483 INFO 15668 --- [ myTask-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 22:00:44.483 INFO 15668 --- [ myTask-2] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask01 doing ...
2022-04-11 22:00:49.498 INFO 15668 --- [ myTask-2] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask01 doing ...
2022-04-11 22:00:49.498 INFO 15668 --- [ myTask-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 22:00:54.507 INFO 15668 --- [ myTask-2] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask doing ...
2022-04-11 22:00:54.507 INFO 15668 --- [ myTask-1] c.c.springschedule.task.ScheduledTask : >>>>> ScheduledTask01 doing ...
原文始发于微信公众号(Java技术前沿):SpringBoot 实战: Spring Boot 3种定时任务方式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/299710.html