SpringBoot--定时任务
实现定时任务有多种形式:
Timer(强烈不建议使用): JDK自带的java.util.Timer;通过调度java.util.TimerTask的方式 让程序按照某一个频度执行,但不能在指定时间运行。 一般用的较少。
ScheduledExecutorService(建议不使用): JDK1.5新增的,位于java.util.concurrent包中;是基于线程池设计的定时任务类,每个调度任务都会被分配到线程池中,并发执行,互不影响。
Spring Task(推荐使用): Spring3.0 以后新增了task,一个轻量级的Quartz,功能够用,用法简单。
Quartz(推荐使用): 功能最为强大的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,它还可以动态开关,但是配置起来比较复杂。现如今开源社区中已经很多基于Quartz 实现的分布式定时任务项目(xxl-job、elastic-job)。
本文只阐述前三种,第四种会单独说明基于Quartz的xxl-job。
一、Timer
直接上代码
package com.example.demo.job; import java.time.LocalDateTime; import java.util.Timer; import java.util.TimerTask; public class TimerDemo { public static void main(String[] args){ TimerTask timerTask = new TimerTask() { @Override public void run() { System.out.println("执行任务:" + LocalDateTime.now()); } }; Timer timer = new Timer(); // timerTask:需要执行的任务 // delay:延迟时间(以毫秒为单位) // period:间隔时间(以毫秒为单位) timer.schedule(timerTask, 5000, 3000); } }
运行结果:
二、ScheduledExecutorService
也没有什么可说的,直接上代码:
package com.example.demo.job; import java.time.LocalDateTime; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledExecutorDemo { public static void main(String[] args){ ScheduledExecutorService service = Executors.newScheduledThreadPool(10); // 参数:1、具体执行的任务 2、首次执行的延时时间 // 3、任务执行间隔 4、间隔时间单位 service.scheduleAtFixedRate(()->System.out.println("执行任务A:" + LocalDateTime.now()),0,3,TimeUnit.SECONDS); } }
执行结果:
三、Spring Task
本文着重讲Spring Task。
1、导包
只需要导入spring-boot-starter-web依赖即可,里面已经包含了spring-context,定时任务相关的就属于这个JAR下的org.springframework.scheduling包中。
2、定时任务编写
package com.example.demo.job; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @Component public class SpringTaskDemo { @Async @Scheduled(cron = "0/1 * * * * *") public void schedule1() throws Exception{ Thread.sleep(3000); System.out.println("scheduled1 每1秒执行一次:{}" + LocalDateTime.now()); } @Scheduled(fixedRate = 1000) public void schedule2() throws Exception{ Thread.sleep(3000); System.out.println("scheduled2 每1秒执行一次:{}" + LocalDateTime.now()); } @Scheduled(fixedDelay = 3000) public void schedule3() throws Exception{ Thread.sleep(5000); System.out.println("scheduled3 上次执行完毕后隔3秒继续执行:{}" + LocalDateTime.now()); } }
注释说明:
@Async:异步执行
@Scheduled:定时任务配置
fixedRate--多久执行一次,即下次执行时间=上次执行开始时间+时间间隔;
fixedDelay--执行完之后多久执行下一次,即下次执行时间=上次执行结束时间+时间间隔(如果加上@Async注解,则是异步执行,结束时间即为开始时间,因此下次执行时间=上次执行开始时间+时间间隔)
特别注意,一定要加上@Component注解,否则主函数扫描不到,定时任务不会被执行。
3、主函数配置
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @SpringBootApplication @EnableAsync @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean public TaskScheduler taskScheduler(){ ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(10); return taskScheduler; } }
说明:
@EnableAsync:开启异步注解@Async
@EnableScheduling:开启SpringTask注解@Scheduled
测试结果:
-----------------------------------------------------------
---------------------------------------------
朦胧的夜 留笔~~