2.6 定時任務管理實現類
@Slf4j
@Service
public class ScheduledTaskServiceImpl implements ScheduledTaskService {
/**
* 可重入鎖
*/
private ReentrantLock lock = new ReentrantLock();
/**
* 定時任務線程池
*/
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
/**
* 啟動狀態的定時任務集合
*/
public Map<String, ScheduledFuture> scheduledFutureMap = new ConcurrentHashMap<>();
@Autowired
private ScheduledJobService scheduledJobService;
@Override
public Boolean start(ScheduledJob scheduledJob) {
String jobKey = scheduledJob.getJobKey();
log.info("啟動定時任務"+jobKey);
//添加鎖放一個線程啟動,防止多人啟動多次
lock.lock();
log.info("加鎖完成");
try {
if(this.isStart(jobKey)){
log.info("當前任務在啟動狀態中");
return false;
}
//任務啟動
this.doStartTask(scheduledJob);
} finally {
lock.unlock();
log.info("解鎖完畢");
}
return true;
}
/**
* 任務是否已經啟動
*/
private Boolean isStart(String taskKey) {
//校驗是否已經啟動
if (scheduledFutureMap.containsKey(taskKey)) {
if (!scheduledFutureMap.get(taskKey).isCancelled()) {
return true;
}
}
return false;
}
@Override
public Boolean stop(String jobKey) {
log.info("停止任務 "+jobKey);
boolean flag = scheduledFutureMap.containsKey(jobKey);
log.info("當前實例是否存在 "+flag);
if(flag){
ScheduledFuture scheduledFuture = scheduledFutureMap.get(jobKey);
scheduledFuture.cancel(true);
scheduledFutureMap.remove(jobKey);
}
return flag;
}
@Override
public Boolean restart(ScheduledJob scheduledJob) {
log.info("重啟定時任務"+scheduledJob.getJobKey());
//停止
this.stop(scheduledJob.getJobKey());
return this.start(scheduledJob);
}
/**
* 執行啟動任務
*/
public void doStartTask(ScheduledJob sj){
log.info(sj.getJobKey());
if(sj.getStatus().intValue() != 1)
return;
Class? clazz;
ScheduledOfTask task;
try {
clazz = Class.forName(sj.getJobKey());
task = (ScheduledOfTask) SpringContextUtil.getBean(clazz);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("spring_scheduled_cron表數據" + sj.getJobKey() + "有誤", e);
}
Assert.isAssignable(ScheduledOfTask.class, task.getClass(), "定時任務類必須實現ScheduledOfTask接口");
ScheduledFuture scheduledFuture = threadPoolTaskScheduler.schedule(task,(triggerContext -> new CronTrigger(sj.getCronExpression()).nextExecutionTime(triggerContext)));
scheduledFutureMap.put(sj.getJobKey(),scheduledFuture);
}
@Override
public void initTask() {
List
2.8 上面用到的獲取Bean的工具類SpringContextUtil
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringContextUtil.applicationContext == null){
SpringContextUtil.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
public static
2.9 表操作對應的一些類
Pojo
@Data
@TableName("scheduled_job")
public class ScheduledJob {
@TableId(value = "job_id",type = IdType.AUTO)
private Integer jobId;
private String jobKey;
private String cronExpression;
private String taskExplain;
private Integer status;
}
ScheduledJobMapper
public interface ScheduledJobMapper extends BaseMapper<ScheduledJob> {
}
ScheduledJobService
public interface ScheduledJobService extends IService<ScheduledJob> {
/**
* 修改定時任務,并重新啟動
* @param scheduledJob
* @return
*/
boolean updateOne(ScheduledJob scheduledJob);
}
@Service
@Slf4j
public class ScheduledJobServiceImpl extends ServiceImpl
2.10 修改定時任務的接口
@RestController
@RequestMapping("/job")
public class ScheduledJobController {
@Autowired
private ScheduledJobService scheduledJobService;
@PostMapping(value = "/update")
public CallBackResult update(HttpServletRequest request, ScheduledJob scheduledJob){
if(scheduledJobService.updateOne(scheduledJob))
return new CallBackResult(true,"修改成功");
return new CallBackResult(false,"修改失敗");
}
}
3、測試結果
3.1 啟動項目,看下定時任務的執行結果,控制臺輸出結果
我們可以看到任務1是每5秒執行一次,任務2是12秒執行一次
3.2 修改任務1的cron參數或者狀態
3.2.1 修改cron,執行周期改為20秒執行一次,狀態不變
再看控制臺輸出結果,任務2沒變化,任務1由5秒一次變成了20秒一次了
3.2.1 修改狀態
再看控制臺輸出結果,任務2沒變化,任務1已經不再執行了
最后
第二種方式支持通過接口的方式去改動,并且不需要重啟,當然啦,也可以直接在數據庫中添加或修改數據后重啟項目,配置更加靈活一點。
如果是一個固定的需求,執行周期一定不會變的了,推薦還是第一種寫法,畢竟簡單嘛。
如果覺得寫得還不錯的話,給個推薦鼓勵一下吧。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
代碼
+關注
關注
30文章
4821瀏覽量
68890 -
spring
+關注
關注
0文章
340瀏覽量
14368 -
Boot
+關注
關注
0文章
150瀏覽量
35888 -
SpringBoot
+關注
關注
0文章
174瀏覽量
190
發布評論請先 登錄
相關推薦
關于stm32系統定時任務的問題
選取的還是計算得到的?就是他怎么知道在 1ms的時候做這個任務,在2ms的時候做另一個,而且沒有3ms 的定時任務?還有就是什么情況下需要使用這種系統循環任務?
發表于 10-10 23:43
Linux系統定時任務Crond
會定期(默認每分鐘檢查一次)檢查系統中是否有要執行的任務工作,如果有,便會根據其預先設定的定時任務規則自動執行該定時任務工作,這個crond定時任務服務就相當于我們平時早起使用的鬧鐘一
發表于 07-05 06:22
定時任務的發展史是怎么樣的
定時任務是互聯網行業里最常用的服務之一,本文給大家介紹定時任務在我司的發展歷程。 linux系統中一般使用crontab命令來實現,在Java世界里,使用最廣泛的就是quartz了。我司
發表于 07-18 17:38
?0次下載
SpringBoot如何實現動態增刪啟停定時任務
這兩種方式不能動態添加、刪除、啟動、停止任務。 要實現動態增刪啟停定時任務功能,比較廣泛的做法是集成Quartz框架。但是本人的開發原則是:在滿足項目需求的情況下,盡量少的依賴其它框架
Python定時任務的實現方式
在日常工作中,我們常常會用到需要周期性執行的任務,一種方式是采用 Linux 系統自帶的 crond 結合命令行實現。另外一種方式是直接使用Python。接下來整理的是常見的Python定時任務
如何在SpringBoot項目中實現動態定時任務
之前寫過文章記錄怎么在SpringBoot項目中簡單使用定時任務,不過由于要借助cron表達式且都提前定義好放在配置文件里,不能在項目運行中動態修改任務執行時間,實在不太靈活。
解析Golang定時任務庫gron設計和原理
正巧,最近看到了 gron 這個開源項目,它是用 Golang 實現一個并發安全的定時任務庫。實現非常簡單精巧,代碼量也不多。今天我們就來一起結合源碼看一下,怎樣基于 Golang 的
求一種SpringBoot定時任務動態管理通用解決方案
SpringBoot的定時任務的加強工具,實現對SpringBoot原生的定時任務進行動態管理,完全兼容原生@Scheduled注解,無需對
SpringBoot如何實現定時任務(上)
SpringBoot創建定時任務的方式很簡單,主要有兩種方式:一、基于注解的方式(@Scheduled)二、數據庫動態配置。實際開發中,第一種需要在代碼中寫死表達式,如果修改起來,又得重啟會顯得很麻煩;所以我們往往會采取第二種方式,可以直接從數據庫中讀取
如何動態添加修改刪除定時任務?
如何動態添加修改刪除定時任務?那么我們一起看看具體怎么實現,先看下本節大綱:
(1)思路說明;
(2)代碼解析;
(3)修改定時任務執行周期特別說明;
Linux如何使用cron進行定時任務的操作
按計劃執行命令對于計算機來說非常重要,因為假如我親自去執行一些任務的話,可能會因為多方面因素不能按時執行,所以定時任務就顯得非常重要了!
cron就是一個能夠執行定時任務的命令,其實該命令本身不難,下面小編帶您詳細了解!
定時器如何實現定時任務
1.1、單次定時任務實現 boost 的asio庫里有幾個定時器,老的有 deadline_timer , 還有三個可配合 C++11 的 chrono
評論