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配合使用,指定所使用的時區。若不設置,則使用當前時區。 |