Springboot使用@Scheduled配置定時任務

Springboot使用@Scheduled配置定時任務

串行方式

使用的註解: @Scheduled
應用啓動類添加註解:@EnableScheduling
代碼示例:

package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class TestJob {
    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        log.info("Hello World!");
    }
}

打印日誌如下:

2019-09-28 19:02:15.002 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:20.001 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:25.003 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!

定時任務Cron配置可參考:https://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html

並行執行

串行執行的時候,可能會出現線程阻塞導致執行延時的情況.
代碼示例:

package com.bin.kong.csdnspider.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000*10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec2() {
        log.info("World Hello!" );
    }
}


結果打印,exec2的執行時間延時變成了15秒:
在這裏插入圖片描述

解決辦法

1.使用線程池的方式:
配置方法可參考: Springboot線程池配置管理
代碼示例:

package com.bin.kong.csdnspider.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000*10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    @Async("threadExecutor")
    public void exec2() {
        log.info("World Hello!" );
    }
}

2.使用Executors的方式

代碼示例:

package com.bin.kong.csdnspider.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000 * 10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec2() {
        ExecutorService service = Executors.newFixedThreadPool(5);
        service.execute(() -> {
            log.info("World Hello!");
        });
    }
}

3.將Scheduled配置成多線程執行的方式
示例代碼:

package com.bin.kong.csdnspider.job;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executors;

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }
}

參數列表

參數名 描述
corn 可以使用Cron表達式來配置定時任務
fixedRate 該屬性的含義是上一次調用開始後再次調用的延時(不用等待上一次調用完成)
fixedRateString 含義同fixedRate,只是參數是String類型
fixedDelay 該屬性的含義是等一上次調用執行完成後再次調用的延時(需要等上一次調用完成)
fixedDelayString 含義同fixedDelay,只是參數是String類型
initialDelay 該屬性的含義是第一次執行的延時,需配合fixedRate等其他參數使用
initialDelayString 含義同initialDelay,只是參數是String類型
zone 與cron配合使用,指定所使用的時區。若不設置,則使用當前時區。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章