前言
定时任务实现的几种方式:
Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
ScheduledExecutorService:也jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
Spring Task:Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
Quartz:这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
Timer
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class TestTimer { public static void main(String[] args) { TimerTask timerTask = new TimerTask() { @Override public void run() { System.out.println("task run:"+ new Date()); } }; Timer timer = new Timer(); timer.schedule(timerTask,10,3000); } }
|
ScheduledExecutorService
1 2 3 4 5 6 7 8
| public class TestScheduledExecutorService { public static void main(String[] args) { ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS); } }
|
Spring Task
简单定时任务
启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.qn;
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Arrays;
@MapperScan("com.qn.mapper") @SpringBootApplication @ServletComponentScan @EnableAsync @EnableScheduling public class SpringbootDemoApplication {
public static void main(String[] args) { SpringApplication.run(SpringbootDemoApplication.class, args); }
@Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } }; } }
|
Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.qn.service;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service;
@Service public class ScheduledService { @Scheduled(cron = "0/5 * * * * *") public void scheduled(){ System.out.println("=====>>>>>使用cron {}" + System.currentTimeMillis()); } @Scheduled(fixedRate = 5000) public void scheduled1() { System.out.println("=====>>>>>使用fixedRate{}" + System.currentTimeMillis()); } @Scheduled(fixedDelay = 5000) public void scheduled2() { System.out.println("=====>>>>>fixedDelay{}" + System.currentTimeMillis()); } }
|
多线程执行
确认开启异步,创建线程池配置,详情见上文
然后在定时任务的类或者方法上添加@Async 。最后重启项目,每一个任务都是在不同的线程中。
Quartz
依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
|
任务类
1 2 3 4 5 6 7 8 9 10 11
| public class TestQuartz extends QuartzJobBean {
@Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("quartz task "+new Date()); } }
|
配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Configuration public class QuartzConfig { @Bean public JobDetail teatQuartzDetail(){ return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build(); }
@Bean public Trigger testQuartzTrigger(){ SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) .repeatForever(); return TriggerBuilder.newTrigger().forJob(teatQuartzDetail()) .withIdentity("testQuartz") .withSchedule(scheduleBuilder) .build(); } }
|