SpringBoot基础教程3-1-1 简单定时任务方法介绍

1 概述

定时任务,特定的时间执行任务,在项目中普遍使用。本文介绍简单的无状态无持久化的定时任务实现方式;TimerScheduledExecutorServiceSpring Task

2 Timer实现方式

JDK自带的java.util.Timer;通过调度java.util.TimerTask的方式 让程序按照某一个频度执行,但不能在指定时间运行。 一般用的较少。

/**  
 *    基于 Timer 实现的定时调度,基本就是手撸代码,目前应用较少,不是很推荐
 *   
 * @author Mkeeper  
 * @create 2018/9/28 11:12
 */
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);

    }
}

3 ScheduledExecutorService实现方式

ScheduledExecutorService,JDK1.5新增的,位于java.util.concurrent包中;是基于线程池设计的定时任务类,每个调度任务都会被分配到线程池中,并发执行,互不影响。

Timer很类似,但它的效果更好;多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中有一个因任务报错没有捕获抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService则可以规避这个问题

/**  
 *   优于Timer
 * @author Mkeeper  
 * @create 2018/9/28 11:15
 */
public class ScheduledExecutorServiceDemo {

    public static void main(String[] args) {
        final ScheduledExecutorService service = Executors.newScheduledThreadPool(3);

        // 参数:
        // 1、具体执行的任务
        // 2、首次执行的延时时间
        // 3、任务执行间隔
        // 4、间隔时间单位
        service.scheduleAtFixedRate(() ->
                System.out.println("执行任务:" + LocalDateTime.now()),
                0, 3, TimeUnit.SECONDS
        );
    }
}

4 Spring Task实现方式(推荐)

Spring TaskSpring3.0 以后新增了task,一个轻量级的Quartz,功能够用,用法简单。

Spring Taskspring-contextorg.springframework.scheduling下,只需要依赖spring-boot-starter-web即可。

@Scheduled注解, Spring Task定时任务的核心

  • croncron表达式,根据表达式循环执行,与fixedRate属性不同的是它是将时间进行了切割。@Scheduled(cron = "0/5 * * * * *"任务将在5、10、15、20...这种情况下执行。
  • fixedRate: 每隔多久执行一次;@Scheduled(fixedRate = 1000假设第一次工作时间为2018-09-28 10:58:28,工作时长为3秒,那么下次任务的时候就是2018-09-28 10:58:31配置成异步后,只要到了执行时间就会开辟新的线程工作,如果@Scheduled(fixedRate = 1000假设第一次工作时间为2018-09-28 10:58:28,工作时长为3秒,那么下次任务的时间是2018-09-28 10:58:29
  • fixedDelay: 当前任务执行完毕后等待多久继续下次任务@Scheduled(fixedDelay = 3000假设第一次任务工作时间为2018-09-28 10:58:30,工作时长为5秒,那么下次任务的时间就是2018-09-28 10:58:38
  • initialDelay: 第一次执行延迟时间,只是做延迟的设定,与fixedDelay关系密切,配合使用,相辅相成。

@Async注解,代表该任务可以进行异步工作,由串行改为并行。

cron表达式在线生成http://www.pdtools.net/tools/becron.jsp

@Component
@Slf4j
public class SpringTaskDemo {

    @Async
    @Scheduled(cron = "0/1 * * * * *")
    public void scheduled1() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        log.info("schedule1 每1m秒执行一次: {}", LocalDateTime.now());
    }

    @Scheduled(fixedRate = 1000)
    public void scheduled2() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        log.info("schedule2 每1m秒执行一次: {}", LocalDateTime.now());
    }

    @Scheduled(fixedDelay = 3000)
    public void scheduled3() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        log.info("scheduled3 上次执行完毕后隔3秒继续执行:{}", LocalDateTime.now());
    }

}

开启任务

  • @EnableScheduling注解表示开启对@Scheduled注解的解析;同时new ThreadPoolTaskScheduler()也是相当的关键,通过阅读过源码可以发现默认情况下的 private volatile int poolSize = 1;这就导致了多个任务的情况下容易出现竞争情况,多个任务的情况下,如果第一个任务没执行完毕,后续的任务将会进入等待状态
  • @EnableAsync注解表示开启@Async注解的解析;作用就是将串行化的任务给并行化。
@EnableAsync
@EnableScheduling
@Configuration
public class TaskSchedulerConfig {
   
    @Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }
}

5 测试结果

请自己动动手

6 工程目录

7 结束语

后续文章会陆续介绍,Quartz,以及基于Quartz实现的分布式任务项目,xxl-jobelastic-job,尽情期待。本文源码


欢迎关注博主公众号,第一时间推送最新文章

欢迎关注博主公众号

转载于:https://my.oschina.net/Mkeeper/blog/2221350

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值