SpringBoot:實現定時任務

1、定時任務實現的幾種方式:

  • Timer

    這是java自帶的java.util.Timer類,這個類容許你調度一個java.util.TimerTask任務。使用這種方式可讓你的程序按照某一個頻度執行,但不能在指定時間運行。通常用的較少。java

  • ScheduledExecutorService

    也jdk自帶的一個類;是基於線程池設計的定時任務類,每一個調度任務都會分配到線程池中的一個線程去執行,也就是說,任務是併發執行,互不影響。git

  • Spring Task

    Spring3.0之後自帶的task,能夠將它當作一個輕量級的Quartz,並且使用起來比Quartz簡單許多。github

  • Quartz

    這是一個功能比較強大的的調度器,可讓你的程序在指定時間執行,也能夠按照某一個頻度執行,配置起來稍顯複雜。spring

2、基於SpringBoot的定時任務

使用SpringBoot 自帶的定時任務,只須要添加相應的註解就能夠實現

2.1 導入SpringBoot啓動包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

2.2 啓動類啓用定時

在啓動類上面加上@EnableScheduling便可開啓定時springboot

@SpringBootApplication
@EnableScheduling // 開啓定時
public class SpringBootDemoTimeTaskApplication {

    private static final Logger logger = LoggerFactory.getLogger(SpringBootDemoTimeTaskApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoTimeTaskApplication.class);
        logger.info("SpringBootDemoTimeTaskApplication start!");
    }
}

2.3 建立定時任務實現類SchedulerTask

@Component
public class SchedulerTask {
    private static final Logger logger = LoggerFactory.getLogger(SchedulerTask.class);

    /**
     * @Scheduled(fixedRate = 6000) :上一次開始執行時間點以後6秒再執行
     * @Scheduled(fixedDelay = 6000) :上一次執行完畢時間點以後6秒再執行
     * @Scheduled(initialDelay=1000, fixedRate=6000) :第一次延遲1秒後執行,以後按fixedRate的規則每6秒執行一次
     * @Scheduled(cron=""):詳見cron表達式http://www.pppet.net/
     */

    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        logger.info("=====>>>>>使用fixedRate執行定時任務");
    }
    @Scheduled(fixedDelay = 10000)
    public void scheduled2() {
        logger.info("=====>>>>>使用fixedDelay執行定時任務");
    }

    @Scheduled(cron="*/6 * * * * ?")
    private void scheduled3(){
        logger.info("使用cron執行定時任務");
    }
}

運行結果:多線程

2019-03-09 17:33:05.681  INFO 7752 --- [           main] c.v.t.SpringBootDemoTimeTaskApplication  : SpringBootDemoTimeTaskApplication start!
2019-03-09 17:33:06.002  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : 使用cron執行定時任務
2019-03-09 17:33:10.680  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:12.003  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : 使用cron執行定時任務
2019-03-09 17:33:15.676  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:15.676  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedDelay執行定時任務
2019-03-09 17:33:18.002  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : 使用cron執行定時任務
2019-03-09 17:33:20.677  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:24.002  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : 使用cron執行定時任務
2019-03-09 17:33:25.680  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:25.681  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedDelay執行定時任務
2019-03-09 17:33:30.005  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : 使用cron執行定時任務
2019-03-09 17:33:30.680  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:35.680  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedRate執行定時任務
2019-03-09 17:33:35.682  INFO 7752 --- [   scheduling-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用fixedDelay執行定時任務

2.4 執行時間的配置

在上面的定時任務中,咱們在方法上使用@Scheduled註解來設置任務的執行時間,而且使用三種屬性配置方式:併發

  1. fixedRate:定義一個按必定頻率執行的定時任務
  2. fixedDelay:定義一個按必定頻率執行的定時任務,與上面不一樣的是,改屬性能夠配合initialDelay, 定義該任務延遲執行時間。
  3. cron:經過表達式來配置任務執行時間--在線cron表達式生成器

3、多線程執行定時任務

SpringBoot定時任務默認單線程,能夠看到三個定時任務都已經執行,而且使同一個線程中( scheduling-1)串行執行,若是隻有一個定時任務,這樣作確定沒問題,當定時任務增多, 若是一個任務卡死,會致使其餘任務也沒法執行

3.1 多線程配置類 AsyncConfig.class

@Configuration // 代表該類是一個配置類
@EnableAsync // 開啓異步事件的支持
public class AsyncConfig {
    
    @Value("${myProps.corePoolSize}")
    private int corePoolSize;
    @Value("${myProps.maxPoolSize}")
    private int maxPoolSize;
    @Value("${myProps.queueCapacity}")
    private int queueCapacity;

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

3.2 配置文件application.yml中添加多線程配置

myProps:
  corePoolSize: 10
  maxPoolSize: 100
  queueCapacity: 10

3.3 在定時任務的類或者方法上添加@Async

此時,可以讓每個任務都是在不一樣的線程中,啓動項目,日誌打印以下:
2019-03-11 15:16:54.855  INFO 10782 --- [           main] c.v.t.SpringBootDemoTimeTaskApplication  : SpringBootDemoTimeTaskApplication start!
2019-03-11 15:16:55.015  INFO 10782 --- [ taskExecutor-1] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:00.002  INFO 10782 --- [ taskExecutor-2] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:00.002  INFO 10782 --- [ taskExecutor-3] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:05.003  INFO 10782 --- [ taskExecutor-4] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:06.005  INFO 10782 --- [ taskExecutor-5] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:10.004  INFO 10782 --- [ taskExecutor-6] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:12.005  INFO 10782 --- [ taskExecutor-7] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:15.006  INFO 10782 --- [ taskExecutor-8] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1
2019-03-11 15:17:18.004  INFO 10782 --- [ taskExecutor-9] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-2
2019-03-11 15:17:20.004  INFO 10782 --- [taskExecutor-10] cn.van.task.service.SchedulerTask        : =====>>>>>使用cron執行定時任務-1

日誌打印證實了個人預測,至此,多線程中執行定時任務完畢!app

4、源碼及其延伸

https://github.com/vanDusty/SpringBoot-Home/tree/master/springboot-demo-list/task-demo異步

相關文章
相關標籤/搜索