網站首頁 編程語言 正文
一般情況下定時任務的使用常見的兩個組件:xxl-job和quartz,這兩種需要引用相應的依賴,針對對定時任務較為復雜和依賴性較高的系統
但是如果項目中使用定時任務的場景不多,避免項目過于臃腫和復雜,但要求可配置、可刪除、可啟停用的
定時任務的必要字段
TASK_NAME: 定時任務名稱;
TASK_CRON:定時任務執行頻率,cron表達式
TASK_BEAN: 執行定時任務的Bean名稱
TASK_MOTHOD: 執行定時任務的方法名
一、創建線程池并設置參數
ThreadPoolTaskScheduler:
主要用于任務調度,可以按照時間間隔或Cron表達式來執行任務。
繼承自TaskScheduler接口,并實現了AsyncTaskExecutor接口。
它基于線程池來執行任務,并且可以根據需要調度任務的執行。特點:
強調任務調度和時間控制。
適用于需要按照特定時間間隔或規則執行任務的場景。
其他線程:
主要用于執行異步任務和多線程任務。
專注于線程池的管理和配置,如線程池的大小、隊列容量以及線程的創建和銷毀策略特點:
強調線程池的管理和異步任務的執行。
適用于需要并發執行大量異步任務的場景。
@Configuration
public class SchedulingConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(4);
taskScheduler.setRemoveOnCancelPolicy(true);
taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");
return taskScheduler;
}
}
二、添加 ScheduledFuture 的包裝類
ScheduledTaskFuture :
主要用于處理和控制定時任務的執行結果和執行狀態。它提供了異步執行結果的獲取、任務執行狀態的控制、任務執行結果的獲取和異常處理、任務的取消以及超時獲取任務結果等功能,使得你可以更加方便地管理和控制定時任務的執行。1、可以通過ScheduledTaskFuture來獲取定時任務執行后的結果,查詢定時任務是否已完成(isDone()方法)、是否已被取消(isCancelled()方法)或者是否正在執行(!isDone() && !isCancelled())。
2、可以調用ScheduledTaskFuture的get()方法來獲取定時任務執行的結果。
3、可以調用cancel(boolean mayInterruptIfRunning)方法來取消定時任務的執行。如果參數mayInterruptIfRunning為true,嘗試中斷正在執行的任務;如果為false,則正在執行的任務不會被中斷,但是等待執行的任務會被取消
@Component
public final class ScheduledTaskFuture {
public volatile ScheduledFuture<?> scheduledFuture;
public void cancel(){
ScheduledFuture<?> future = this.scheduledFuture;
if (future != null) {
future.cancel(true);
}
}
}
三、定時任務實體類
public class DismTimedTask {
/**
* 任務ID
*/
@Id
@Column(name = "TASK_ID")
private Long taskId;
/**
* 任務名稱
*/
@Column(name = "TASK_NAME")
private String taskName;
/**
* 任務執行頻率
*/
@Column(name = "TASK_CRON")
private String taskCron;
/**
* 時間范圍
*/
@Column(name = "TASK_BEAN")
private int taskBean;
/**
* 是否包含
*/
@Column(name = "TASK_METHOD_NAME")
private String taskMethodName;
/**
* 模板狀態
*/
@Column(name = "STATUS")
private String status;
}
四、任務的執行
public class SchedulingRunnable implements Runnable{
/**
* 執行定時任務的Bean名稱
*/
private String beanName;
/**
* 執行定時任務的方法名稱
*/
private String methodName;
/**
* 定時任務的參數、可定義為其他類型
*/
private Long taskId;
public SchedulingRunnable(String beanName, String methodName, Long taskId) {
this.beanName = beanName;
this.methodName = methodName;
this.taskId = taskId;
}
@Override
public void run() {
log.info("定時任務開始執行 - bean: {}, 方法: {}", beanName, methodName);
try {
Object target = SpringContextUtils.getBean(beanName);
if (taskId == null || taskId == 0L) {
// 無參的
Method method = target.getClass().getMethod(methodName);
method.invoke(target);
} else {
//有參的
Method method = target.getClass().getMethod(methodName, Long.class);
method.invoke(target, taskId);
}
} catch (Exception ex) {
log.error(String.format("定時任務執行異常-bean: %s, 方法: %s", beanName, methodName));
log.error("異常:" + ex);
}
log.info("定時任務執行結束 - bean: {}, 方法: {}", beanName, methodName);
}
}
五、定時任務的創建、刪除操作
@Service
@Slf4j
public class TimedTaskServiceImpl implements TimedTaskService {
private final Map<Long, ScheduledTaskFuture> scheduledTasks = new ConcurrentHashMap<>(16);
@Resource
private TaskScheduler taskScheduler;
/**
* 更新定時任務
* @author Liyh
* @date 2024/06/17 09:56
* @param timedTask
*/
@Transactional(rollbackFor = Exception.class)
public void updateTimedTask(TimedTask timedTask) {
//定時任務執行Bean
SchedulingRunnable schedulingRunnable = new SchedulingRunnable(timedTask.getBean(), timedTask.getMothod(), timedTask.getTaskId());
CronTask cronTask = new CronTask(schedulingRunnable, timedTask.getTaskCron());
if ("1".equals(timedTask.getStatus())) {
// 啟用
// 如果定時任務已經存在,先刪后增,
if (this.scheduledTasks.containsKey(timedTask.getTaskId())){
removeCronTask(timedTask.getTaskId());
}
this.scheduledTasks.put(timedTask.getTaskId(), scheduledTask(cronTask));
} else {
// 停用
removeCronTask(timedTask.getTaskId());
}
}
/**
* 刪除定時任務
* @author Liyh
* @date 2024/06/11 17:41
* @param taskId
*/
public void removeCronTask(Long taskId){
ScheduledTaskFuture scheduledTask = this.scheduledTasks.remove(taskId);
if (scheduledTask != null) {
scheduledTask.cancel();
}
}
/**
* 創建定時任務
* @author Liyh
* @date 2024/06/11 17:41
* @param cronTask
* @return ScheduledTaskFuture
*/
public ScheduledTaskFuture scheduledTask(CronTask cronTask){
ScheduledTaskFuture scheduledTask = new ScheduledTaskFuture();
scheduledTask.scheduledFuture = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
return scheduledTask;
}
}
/*刪除任務時執行removeCronTask方法即可*/
六、獲取Bean的工具類
@Component
public class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
}
7、程序啟動時加載數據庫中啟用的任務
@Component
public class TimedTaskRunner implements CommandLineRunner {
@Resource
private TimedTaskService timedTaskService;
@Override
public void run(String... args) throws Exception {
timedTaskService.runAllTimedTask();
}
}
具體實現類方法
public void runAllTimedTask() {
List<DismTimedTask> timedTaskList = timedTaskDao.getDismTimedTaskByStatus("1");
if (timedTaskList != null && !timedTaskList.isEmpty()) {
for (DismTimedTask timedTask : timedTaskList) {
SchedulingRunnable schedulingRunnable = new SchedulingRunnable(null, "taskRunning", timedTask.getTaskId());
CronTask cronTask = new CronTask(schedulingRunnable, timedTask.getTaskCron());
scheduledTask(cronTask);
this.scheduledTasks.put(timedTask.getTaskId(), scheduledTask(cronTask));
log.info("定時任務已加載完畢...");
}
}
}
原文鏈接:https://blog.csdn.net/saonian0929/article/details/139850453
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-10-05 C語言各種符號的使用介紹下篇_C 語言
- 2023-02-23 C語言整形提升舉例詳解_C 語言
- 2022-10-08 Python中集合創建與使用詳解_python
- 2022-07-08 C#使用GDI+實現生成驗證碼_C#教程
- 2023-01-18 GO實現跳躍表的示例詳解_Golang
- 2023-01-10 redis中Could?not?get?a?resource?from?the?pool異常及解決方
- 2022-10-31 Kotlin類的繼承實現詳細介紹_Android
- 2022-10-03 C語言實現經典排序算法的示例代碼_C 語言
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支