springboot集成常见定时任务
一、常见定时任务
原文转载
https://mp.weixin.qq.com/s/9GRxBCpeDss-llecrwo-lw
1、创建方式
- 使用线程创建
- 使用TimerTask创建
- 使用线程池创建
- 使用Quartz创建
- 使用springboot的@Scheduled注解
2、线程创建
public class CreatByThread {
private static int count = 0;
private static void timerTask(){
Runnable runnable = new Runnable() {
@SneakyThrows
@Override
public void run() {
while (true){
Thread.sleep(1000);
count++;
System.err.println(count);
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
public static void main(String[] args) {
timerTask();//原生写法
new Thread(()->{//lambda表达式
while (true){
try {
Thread.sleep(1000);
count++;
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
3、TimerTask创建
原文转载
https://blog.csdn.net/xieyuooo/article/details/8607220/
首先要明白:Timer是一个调度器,TimerTask只是一个实现了run方法的一个类(需要自己来实现)
Timer和TimerTask的组合是一个单线程,如果创建多线程会使用:Executor.newScheduledThreadPool
常见的Timer类中的方法:
#调度一个task,经过dealy(ms)后开始调度,仅仅调度一次 public void schedule(TimerTask task,long delay)
#调度一个task,在指定的时间点time上调度一次 public void schedule(timertask task,Date t)
#调度一个task,在dealy(ms)后开始调度,每次调度完后,最少等待period(ms)后才开始调度 public void schedule(TimerTask task,long delay,long period)
#和上一个方法类似,唯一区别就是传入的第二个参数为第一次调度的时间 public void schedule(TimerTask task,Date firstTime,long period)
#调度一个task,在delay(ms)后开始调度,然后经过period(ms)再次调度,似乎和第三个方法类似,但不然,区别: #1、schedule在计算下一次执行时间的时候,是通过当前时间(在任务执行前得到)+时间片; #2、scheduleAtFixedRate方法是通过当前需要执行的时间(也就是现在需要执行的时间)+时间片; #3、schedule是运行时的实际时间,而scheduleAtFixedRate是理论时间。例如:schedule的时间片是5s,那么理论会在5、10、15、20这些时间片被调度,但如果由于某些cpu征用导致未调度,假如等到8s才被调度一次,那么schedule方法计算出来的下一次调度时间应该是13s,而不是10s,这样有可能下次越到20s后而被少调度一次或多次;而scheduleAtFixedRate就是每次理论计算出下一次需要调度的时间用以排序,若第8s被调度了,那么计算出应该是第10s,所以它距离当前时间是2s,那么在调度队列排序中,会优先调度; #4、scheduleAtFixedRate可以减少漏调度的情况; public void scheduleAtFixedRate(TimerTask timer,long delay,long period)
#方法和上一个方法类似,唯一的区别是第一次调度的时间设置为Date,而不是当前时间的一个时间片 public void scheduleAtFixedRate(TimerTask timer,Date firstTime,long period)
public class CreatByTimerTask {
private static int count = 0;
private static void timerTask(){
TimerTask timerTask = new TimerTask() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(1000);
count++;
System.err.println(count);
}
};
Timer timer = new Timer();
timer.schedule(timerTask,0,1000);//每秒调度一次
}
public static void main(String[] args) {
timerTask();//原生写法
new Timer().schedule(new TimerTask() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(1000);
count++;
System.out.println(count);
}
},0,1000);
}
}
4、使用线程池创建
public class CreatByThreadPool {
private static int count = 0;
private static void timerTask(){
Runnable runnable = new Runnable() {
@Override
public void run() {
count++;
System.err.println(count);
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
//第二个参数为首次执行的延迟时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable,1,1, TimeUnit.SECONDS);
}
public static void main(String[] args) {
timerTask();
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->{
count++;
System.out.println(count);
},1,1,TimeUnit.SECONDS);
}
}
5、使用Quartz创建
-
maven依赖
<!--Quartz--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency>
-
实现了Quratz框架接口的类
@Service public class QuartzServiceImpl implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.err.println("this is a quartz method , now time:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }
-
启动类
public class creatByQuartz { private static void timerTask() throws SchedulerException { //1、创建scheduler的工厂 StdSchedulerFactory factory = new StdSchedulerFactory(); //2、从工厂中获取调度器实列 Scheduler scheduler = factory.getScheduler(); //3、创建JobDetail JobDetail job = JobBuilder.newJob(QuartzServiceImpl.class) //job描述 .withDescription("this is a quartz job") //job的name和group .withIdentity("quartzJob", "quartzGroup") .build(); //任务运行的时间,simpleSchedule类型触发器有效,3秒后启动任务 long time = System.currentTimeMillis()+3*1000L; Date statTime = new Date(time); //4、创建Trigger(使用SimpleScheduleBuilder或者CronScheduleBuilder) CronTrigger trigger = TriggerBuilder.newTrigger() .withDescription("this is trigger") .withIdentity("quartzTrigger", "quartzTriggerGroup") // .withSchedule(SimpleScheduleBuilder.simpleSchedule()) .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))//两秒执行一次,采用cron表达式 .startAt(statTime)//默认当前时间启动 .build(); //5、注册任务和定时器 scheduler.scheduleJob(job,trigger); //6、启动调度器 scheduler.start(); } public static void main(String[] args) throws SchedulerException { timerTask(); } }
1、Quartz相关builder
https://blog.csdn.net/yjltx1234csdn/article/details/105846493
https://www.cnblogs.com/sunset-red/p/13794009.html
6、springboot的@Scheduled注解
-
在启动类上添加注解:@EnableScheduling
@Slf4j @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//排除连接数据库 @EnableAspectJAutoProxy(proxyTargetClass = true) @EnableScheduling //开启定时任务 public class IdempotencyApplication { public static void main(String[] args) throws UnknownHostException { ConfigurableApplicationContext applicationContext = SpringApplication.run(IdempotencyApplication.class, args); ConfigurableEnvironment env = applicationContext.getEnvironment(); String ip = Inet6Address.getLocalHost().getHostAddress(); String port = env.getProperty("server.port"); String path = env.getProperty("server.servlet.context-path"); log.info("----------------------------------\r\n{}","http://".concat(ip).concat(":").concat(port+path)); } }
-
用注解:@Scheduled标识定时任务方法
@Configuration @Component public class CreatByScheduled { // @Scheduled(cron = "0/5 * * * * ?")//采用cron表达式执行一次定时任务 @Scheduled(fixedRate = 5000)//指定时间5s执行一次定时任务 public static void timerTask(){ System.err.println("this is a timerTask:"+ LocalDate.now()); } }
-
项目启动后,定时任务执行
-
cron表达式说明
https://blog.csdn.net/hu_dongyang/article/details/114270232
-
springboot使用@Scheduled
https://www.jianshu.com/p/c7492aeb35a1