在項目日常開發過程中,經常需要定時任務來幫我們做一些工作,如清理日誌。定時任務的實現方法主要有 Timer、Quartz 以及 elastic-job
Timer 實現定時任務
只執行一次的定時任務
Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("2000毫米後執行一次。"); } }, 2000); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("5000毫米後執行一次。"); } }, new Date(System.currentTimeMillis() + 5000));
循環執行任務
Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println(111); } }, 1000, 2000); // 1000毫米後執行第一次,之後每2000毫米執行一次
終止任務
timer.concel();
Timer 是 JDK 實現的定時任務,用起來簡單、方便,對一些簡單的定時任務可以使用它。由於它不支持 cron 表達式,現在已經很少用了。
Quartz 實現定時任務
Quartz 是一個完全由 Java 編寫的開源作業調度框架,可以用它來實現定時任務。
在 pom.xml 文件添加 Quartz 依賴
org.quartz-schedulerquartz2.2.1org.quartz-schedulerquartz-jobs2.2.1org.slf4jslf4j-api1.7.25org.slf4jslf4j-simple1.7.6
編寫 Job
定時執行的任務
public class QuartzJob implements Job{ public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); String hello = (String) jobDataMap.get("hello"); System.err.println(hello); } }
編寫 Task
public void task() { // 該 map 可在 job 中獲取 JobDataMap map = new JobDataMap(); map.put("hello", "world"); JobDetail jobDetail = newJob(QuartzJob.class). withIdentity("myJob", "myGroup"). setJobData(map).build(); /* * 簡單定時器 * * 執行時間間隔 * withIntervalInMilliSeconds 毫秒 * withIntervalInSeconds 秒 * withIntervalInMinutes 分鐘 * withIntervalInHours 小時 * * 執行次數 * repeatForever 重複執行 * withRepeatCount 次數 */ SimpleScheduleBuilder scheduleBuilder = simpleSchedule().withIntervalInSeconds(3).withRepeatCount(10); /* * corn定時器 * * corn表達式,使用更靈活 * corn表達式在線生成 http://cron.qqe2.com/ */ CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0 1 * ?"); Trigger trigger = newTrigger().startAt(new Date()).//startNow() 默認現在開始 withIdentity("myTrigger", "myGroup"). //withSchedule(scheduleBuilder).build(); withSchedule(cronScheduleBuilder).build(); try { //1.創建Scheduler工廠 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); //2.獲取實例 Scheduler scheduler = schedulerFactory.getScheduler(); //3.設置jobDetail詳情和trigger觸發器 scheduler.scheduleJob(jobDetail, trigger); //4.定時任務開始 scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } }
在項目啟動的時候調用 task 方法即可啟動定時任務。
Spring Boot 創建定時任務
Spring Boot 默認已經實現了定時任務,只需要添加相應的註解即可完成
pom.xml 文件配置
pom.xml 不需要添加其他依賴,只需要加入 Spring Boot 依賴即可,這裡我們添加一個 web 和 test 的依賴
org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-devtoolstrue
在啟動類上面加上 @EnableScheduling 註解
在啟動類上面加上 @EnableScheduling 註解即可開啟定時任務
@EnableScheduling @SpringBootApplication public class SchedulingApplication { public static void main(String[] args) { SpringApplication.run(SchedulingApplication.class, args); } }
編寫定時任務
@Component public class ScheduledTask { @Scheduled(initialDelay=1000, fixedDelay = 1000) public void task1() { System.out.println("延遲1000毫秒後執行,任務執行完1000毫秒之後執行!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } @Scheduled(fixedRate = 2000) public void task2() { System.out.println("延遲1000毫秒後執行,之後每2000毫秒執行一次!"); } }
除了這些還支持 cron 表達式
@Scheduled(cron = "*/2 * * * * ?") public void task3() { System.out.println("每2秒執行一次!"); }
啟動 Spring Boot 項目在控制檯就會看到任務定時執行
cron 表達式
以下是 cron 表達式的的兩種語法
Seconds Minutes Hours DayofMonth Month DayofWeek Year Seconds Minutes Hours DayofMonth Month DayofWeek
每一個域可出現的字符如下:
Seconds:可出現", - * /"四個字符,有效範圍為0-59的整數
Minutes:可出現", - * /"四個字符,有效範圍為0-59的整數
Hours:可出現", - * /"四個字符,有效範圍為0-23的整數
DayofMonth:可出現", - * / ? L W C"八個字符,有效範圍為0-31的整數
Month:可出現", - * /"四個字符,有效範圍為1-12的整數或JAN-DEc
DayofWeek:可出現", - * / ? L C #"四個字符,有效範圍為1-7的整數或SUN-SAT兩個範圍。1表示星期天,2表示星期一, 依次類推
Year:可出現", - * /"四個字符,有效範圍為1970-2099年
舉幾個例子
*/2 * * * * ? 表示每2秒執行一次! 0 0 2 1 * ? * 表示在每月的1日的凌晨2點調度任務 0 15 10 ? * MON-FRI 表示週一到週五每天上午10:15執行作業 0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最後一個星期五上午10:15執行作
[hongdian2012 ] SpringBoot中使用@Scheduled註解創建定時任務的實現已經有234次圍觀