Spring多線程通過@Scheduled實現(xiàn)定時任務(wù)
一、前言
技術(shù)的入門大多比較簡單,把別人的代碼復(fù)制過來,刪刪改改,基本也就能實現(xiàn)個功能,查看個API大概也就知道如何實現(xiàn)幾個功能,但是,如果對一項技術(shù)了解的足夠深入,就要知道一個技術(shù)的優(yōu)缺點,以及他存在的問題,這些就需要大量的時間及思考,疾風(fēng)知勁草,只有足夠了解才能臨危不懼,才能在如疾風(fēng)般強勁的bug來臨時微微一笑,絕對不倒!
二、定時任務(wù)調(diào)度注解@Scheduled
這個注解是spring定時任務(wù)中的主角,他包含幾種類型:
- @Scheduled(fixedDelay = 2000)
- @Scheduled(fixedRate = 2000)
- @Scheduled(initialDelay = 1000, fixedDelay = 2000)
- @Scheduled(cron = "*/5 * * * * *")
使用過定時任務(wù)的童鞋應(yīng)該都是使用過以上集中注解,現(xiàn)在簡單介紹一下
- @Scheduled(fixedDelay = 2000) 等上一個任務(wù)執(zhí)行完2s后執(zhí)行
- @Scheduled(fixedRate = 2000) 從上一個任務(wù)開始后的2s,下一個任務(wù)進行執(zhí)行
- @Scheduled(initialDelay = 1000, fixedDelay = 2000) 方法不會立即執(zhí)行 要等initialDelay后再執(zhí)行
- @Scheduled(cron = "*/5 * * * * *") 選定時間進行執(zhí)行
下面重點說一下 @Scheduled(fixedRate = 2000) 他的說明是從上一個任務(wù)開始后的2s,下一個任務(wù)進行執(zhí)行,但是真的如此嗎? 我們來驗證一下
創(chuàng)建一個定時任務(wù)類,及定時任務(wù)方法:
/**
* Spring的定時任務(wù)
*/
@Component
@EnableScheduling
public class ScheduleJob {
@Autowired
private TaskService taskService;
/**
* 和上一個方法的開始和下一個方法的開始固定是2s
* 這種方法適合任務(wù)之間是獨立的
*/
@Scheduled(fixedRate = 2000)
public void fixedRateTaskR() {
taskService.sayHello("fixedRate");
}創(chuàng)建接口:
public interface TaskService {
void sayHello(String type);
}具體實現(xiàn)類:
@Override
public void sayHello(String type) {
try {
long startTime = System.currentTimeMillis() / 1000;
System.out.println(type + " => " + startTime + " - 任務(wù)開始");
System.out.println(type + " => " + "任務(wù)執(zhí)行中");
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}我在執(zhí)行的任務(wù)線程進行延時操作,每次執(zhí)行都會休眠5s,如果每兩秒執(zhí)行一次那么,方法的間隔時間打印出來就是2s,我們執(zhí)行下,
看下結(jié)果:
fixedRate => 1632646194 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646197 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646199 - 任務(wù)開始
結(jié)果很明顯是間隔了5s執(zhí)行一次,而不是2s,說明要等上一個任務(wù)執(zhí)行完下一個任務(wù)才會執(zhí)行,哇塞不哇塞! 既然存在這樣的問題,那如果我就要不等上一個任務(wù)執(zhí)行完,就是要2s執(zhí)行一次能不能干! 當(dāng)然能干!現(xiàn)在就干!
三、使用@Async實現(xiàn)異步調(diào)度
建立spring線程池
/**
* @Description spring線程池配置類
*/
@EnableAsync
@Configuration
public class SendMsgThreadPoolConfig {
@Bean("schedule")
public Executor schduleTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("schedule-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}為異步調(diào)度方法指定線程池
@Override
@Async("schedule")
public void sayHello(String type) {
try {
long startTime = System.currentTimeMillis() / 1000;
System.out.println(type + " => " + startTime + " - 任務(wù)開始");
System.out.println(type + " => " + "任務(wù)執(zhí)行中");
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}我們再執(zhí)行以下,看下輸出結(jié)果:
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646666 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646668 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646671 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632646673 - 任務(wù)開始
看下控制臺,現(xiàn)在的時間間隔就是2s,2s,3s,小伙伴可能就會覺得奇怪了,為啥出現(xiàn)了3s的間隔,這是咋回事,這是因為我們創(chuàng)建的線程池,我們線程池的核心線程和最大線程數(shù)都是2個,每兩秒執(zhí)行一次,前4s兩個線程就被占滿了,第三個任務(wù)執(zhí)行時,要進行等待,因為第一個任務(wù)線程的休眠時間是5s,那么第三個任務(wù)線程在等待1s后會執(zhí)行,這就是間隔3s的原因,驗證一下,將線程數(shù)修改為3個。
看下控制臺輸出:
fixedRate => 1632647147 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632647149 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
fixedRate => 1632647151 - 任務(wù)開始
fixedRate => 任務(wù)執(zhí)行中
這是執(zhí)行時間間隔就為2s了。
到此這篇關(guān)于Spring多線程通過@Scheduled實現(xiàn)定時任務(wù)的文章就介紹到這了,更多相關(guān)Spring定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java開發(fā)中如何使用JVisualVM進行性能分析
JVisualVM是由Sun提供的性能分析工具,如此強大的后盾怎能不強大?在Jdk6.0以后的版本中是自帶的,配置好環(huán)境變量然后在運行中輸入“JVisualVm”或直接到Jdk的安裝目錄的Bin目錄下找到運行程序即可運行。如果是用Jdk1.5或以前版本的朋友就得要單獨安裝了2015-12-12
Java后端產(chǎn)生驗證碼后臺驗證功能的實現(xiàn)代碼
這篇文章主要介紹了Java后臺產(chǎn)生驗證碼后臺驗證功能,本文文字結(jié)合實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06
spring+srpingmvc+hibernate實現(xiàn)動態(tài)ztree生成樹狀圖效果
這篇文章主要介紹了spring+srpingmvc+hibernate動態(tài)ztree生成樹狀圖效果,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11
Java中使用Preconditions來檢查傳入?yún)?shù)介紹
這篇文章主要介紹了Java中使用Preconditions來檢查傳入?yún)?shù)介紹,本文只是作為一個簡單的用法介紹,需要的朋友可以參考下2015-06-06
springboot 實現(xiàn)長鏈接轉(zhuǎn)短鏈接的示例代碼
短鏈接服務(wù)通過將長URL轉(zhuǎn)換成6位短碼,并存儲長短鏈接對應(yīng)關(guān)系到數(shù)據(jù)庫中,用戶訪問短鏈接時,系統(tǒng)通過查詢數(shù)據(jù)庫并重定向到原始URL,實現(xiàn)快速訪問,本文就來介紹一下如何使用,感興趣的可以了解一下2024-09-09

