定时器介绍

  • Java原生定时器Timer:java.util.Timer是JDK自带的定时器,依赖java.util.TimerTask来实现定时任务,实现起来非常简单,但是无法在固定时刻启动,而且在遇到异常情况时会停止执行接下来的定时任务,一般很少在项目中使用。

  • ScheduledExecutorService:java.util.concurrent.ScheduledExecutorService是JDK1.5新增的定时任务执行类,基于线程池构造,可以并发的执行定时任务。

  • SpringTask:Spring3.0新增的定时任务执行组件,与Quartz相比较更轻量一些,而且简单易用,SpringBoot支持的也很好。

  • Quartz:功能最为强大的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,它还可以动态开关,但是配置起来比较复杂。

JavaTimer实现

/**
 * Java timer实现定时器
 */
public class JavaTimer {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            //用于自定义定时器执行的方法
            @Override
            public void run() {
                System.out.println("this is java timer, current time is " + System.currentTimeMillis());
            }
        };

         Timer timer = new Timer();
         /*
         * timerTask:自定义的TimerTask
         * delay:程序运行后,延时多久启动,单位ms
         * period:每次任务执行间隔,单位ms
         */
        timer.schedule(timerTask,10000,1000);
    }
}
  • 测试

ScheduledExecutorService实现

/**
 * ScheduledExecutorService 实现的定时器
 */
public class ScheduledExecutorServiceTimer {

    public static void main(String[] args) {
        //新建一个scheduledExecutorService,线程池初始化大小为5
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
        /**
         * 参数1:runnable,自定义的run方法是定时任务要执行的方法
         * 参数2:initialDelay,初始化后,延迟多久执行
         * 参数3:period,定时任务的执行周期
         * 参数4:timeUnit,initialDelay和period的时间单位,有毫秒、秒、分钟等等
         */
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("this is ScheduledExecutorService timer, current time is " + System.currentTimeMillis());
            }
        },10000,3000, TimeUnit.MILLISECONDS);
    }
}
  • 测试:

SpringBoot集成Spring Task实现:

  • 引入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
  • 编写SpringTask的配置文件
/**
 *  Spring Task 定时器配置类
 */
@Configuration
public class SpringTaskConfig {

    /**
     * 自定义TaskScheduler,并指定TaskScheduler的线程池大小
     * @return
     */
    @Bean
    public TaskScheduler myTaskScheduler(){
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        return threadPoolTaskScheduler;
    }

}
  • 编写定时任务的具体实现
/**
 *  Spring Task 定时器实现类
 */
@Component
public class SpringTaskTimer {

    private static final Logger log = LoggerFactory.getLogger(SpringTaskTimer.class);

    /**
     * cron 表达式,每三秒执行一次
     */
    @Scheduled(cron = "0/3 * * * * *")
    public void testCronSchedule(){
        log.warn("this is spring task ,type is cron,current time is "+ System.currentTimeMillis());
    }

    /**
     * 固定间隔执行一次
     */
    @Async
    @Scheduled(fixedRate = 4000)
    public void testFixedRateSchedule() throws InterruptedException {
        Thread.sleep(1000);
        log.warn("this is spring task ,type is fixedRate,current time is "+ System.currentTimeMillis());
    }

    /**
     * 上次任务执行完成后,再间隔固定时间执行
     */
    @Scheduled(fixedDelay = 6000)
    public void testDelaySchedule() throws InterruptedException {
        Thread.sleep(1000);
        log.warn("this is spring task ,type is fixedDelay,current time is "+ System.currentTimeMillis());
    }
}
  • 标注启动类,使配置生效
@SpringBootApplication
@EnableAsync
@EnableScheduling
public class TimerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TimerApplication.class, args);
    }

}
  • 测试

  • SpringTask相关注解

    • @Scheduled:标注在方法上。cron:表明定时任务的执行规则是根据cron表达式决定的;fixedRate :表明定时任务在固定的时间间隔后便会执行,与任务的执行时间无关;fixedDelay:表明定时任务在执行完成后,再间隔固定的时间后执行,与任务的执行时间有关。
    • @Async:使定时任务可以并行。
    • @EnableScheduling:使Spring Task相关的注解生效。
    • @EnableAsync:使@Async注解生效。

完整的工程代码链接:https://github.com/youzhihua/springboot-training