zoukankan      html  css  js  c++  java
  • Spring Boot (29) 定时任务

    使用场景:数据定时增量同步,定时发送邮件,爬虫定时抓取

    定时任务概述

      定时任务:顾名思义就是在特定/指

    定的时间进行工作,比如我们的手机闹钟,他就是一种定时的任务。

    实现方式:

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

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

      3.Spring Task:spring 3.0以后新增了task,一个轻量级的Quartz,功能够用,用法简单。

      4.Quartz:功能最为强大的调度器,可以让程序在指定时间执行,也可以按照某一个频率执行,他还可以动态开关,但是配置起来比较复杂,现如今开源社区中已经很多基于Quartz 实现的分布式定时任务项目。

    Timer方式

      基于Timer实现的定时调度,目前应用较少,不推荐使用

        @GetMapping("/test")
        public String test() {
    
            TimerTask timerTask = new TimerTask() {
                @Override
                public void run() {
                    System.out.println("执行任务"+ LocalDateTime.now());
                }
            };
            Timer timer = new Timer();
            //参数1 需要执行的任务 参数2 延迟时间毫秒 参数3 间隔时间毫秒
            timer.schedule(timerTask,5000,3000);
    
            return "test";
        }

    ScheduledExecutorService

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

        @GetMapping("/cheduled")
        public String cheduled() {
    
            ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
            //参数1具体执行的任务 2首次执行的延迟时间 3任务执行间隔 4间隔时间单位
            service.scheduleAtFixedRate(()->System.out.println("执行任务"+LocalDateTime.now()),0,3, TimeUnit.SECONDS);
    
            return "cheduled";
        }

    Spring Task(关键)

    导入依赖

    在pom.xml中添加spring-boot-starter-web依赖即可,它包含了spring-context,定时任务相关的就属于这个JAR下的org.springframework.scheduling包中

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    定时任务

    @Scheduled 定时任务的核心

      cron:cron表达式,根据表达式循环执行,与fixedRate属性不同的是它将时间进行了切割

      fixeRate:每隔多久执行一次,无视工作时间(@Scheduled(fixedRate = 1000))假设第一次工作时间为2018-06-15 00:00:00,工作时长为5秒,那么下次任务的时间就是 2018-06-15 00:00:05)

      initialDelay:第一次执行延迟时间,只是做延迟的设定,与fixedDelay关系密切,配合使用。

    @Async 代表任务可以进行一步工作,由原本的串行改为并行

    package com.spring.boot.utils;
    
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.time.LocalDateTime;
    
    @Component
    public class SpringTaskDemo {
        @Async
        @Scheduled(cron = "0/1 * * * * *")
        public void scheduled1() throws InterruptedException {
            Thread.sleep(3000);
            System.out.println("scheduled1 每1秒执行一次" + LocalDateTime.now());
        }
    
        @Scheduled(fixedRate = 1000)
        public void scheduled2() throws InterruptedException {
            Thread.sleep(3000);
            System.out.println("scheduled2 每1秒执行一次" + LocalDateTime.now());
        }
    
    
        @Scheduled(fixedRate = 3000)
        public void scheduled3() throws InterruptedException {
            Thread.sleep(5000);
            System.out.println("scheduled3 航次执行完毕后间隔3秒继续执行" + LocalDateTime.now());
        }
    }

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

    启动类中@EnableScheduling注解 表示开启对@Scheduled注解的解析;同时new ThreadPoolTaskScheduler()也是相当的关键,默认情况下的private volatile int poolSize = 1;这就导致了多个任务的情况下容易出现竞争情况(多个任务的情况下,如果第一个任务没执行完毕,后续的任务将会进入等待状态)。

    @EnableAsync 代表开启@Async异步的解析,并行化运行

    @EnableAsync
    @EnableScheduling
    @SpringBootApplication
    public class BootApplication{
    
        public static void main(String[] args) {
            SpringApplication.run(BootApplication.class,args);
        }
    
        @Bean
        public TaskScheduler taskScheduler(){
            ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            taskScheduler.setPoolSize(10);
            return taskScheduler;
        }
    }

    测试

    启动项目 观察日志信息如下:

    scheduled2 每1秒执行一次2018-06-14T17:33:42.245
    scheduled1 每1秒执行一次2018-06-14T17:33:43.030
    scheduled1 每1秒执行一次2018-06-14T17:33:44.009
    scheduled3 航次执行完毕后间隔3秒继续执行2018-06-14T17:33:44.244
    scheduled1 每1秒执行一次2018-06-14T17:33:45.011
    scheduled2 每1秒执行一次2018-06-14T17:33:45.249
    scheduled1 每1秒执行一次2018-06-14T17:33:46.008
    scheduled1 每1秒执行一次2018-06-14T17:33:47.008
    scheduled1 每1秒执行一次2018-06-14T17:33:48.010
    scheduled2 每1秒执行一次2018-06-14T17:33:48.254
    scheduled1 每1秒执行一次2018-06-14T17:33:49.005
    scheduled3 航次执行完毕后间隔3秒继续执行2018-06-14T17:33:49.247
    scheduled1 每1秒执行一次2018-06-14T17:33:50.008
    scheduled1 每1秒执行一次2018-06-14T17:33:51.006
    scheduled2 每1秒执行一次2018-06-14T17:33:51.258
    scheduled1 每1秒执行一次2018-06-14T17:33:52.006
    scheduled1 每1秒执行一次2018-06-14T17:33:53.008
    scheduled1 每1秒执行一次2018-06-14T17:33:54.007
    scheduled3 航次执行完毕后间隔3秒继续执行2018-06-14T17:33:54.252
    scheduled2 每1秒执行一次2018-06-14T17:33:54.262
    scheduled1 每1秒执行一次2018-06-14T17:33:55.007
    scheduled1 每1秒执行一次2018-06-14T17:33:56.007
    scheduled1 每1秒执行一次2018-06-14T17:33:57.005
    scheduled2 每1秒执行一次2018-06-14T17:33:57.266
    scheduled1 每1秒执行一次2018-06-14T17:33:58.007
    scheduled1 每1秒执行一次2018-06-14T17:33:59.006
    scheduled3 航次执行完毕后间隔3秒继续执行2018-06-14T17:33:59.257
  • 相关阅读:
    PAT B1045 快速排序 (25 分)
    PAT B1042 字符统计 (20 分)
    PAT B1040 有几个PAT (25 分)
    PAT B1035 插入与归并 (25 分)
    PAT B1034 有理数四则运算 (20 分)
    PAT B1033 旧键盘打字 (20 分)
    HDU 1231 最大连续子序列
    HDU 1166 敌兵布阵
    HDU 1715 大菲波数
    HDU 1016 Prime Ring Problem
  • 原文地址:https://www.cnblogs.com/baidawei/p/9184142.html
Copyright © 2011-2022 走看看