当前位置: 首页 > article >正文

在springboot项目中实现一个定时任务执行的功能

前言

  这篇文章教大家在springboot项目中实现一个定时任务执行的功能,并且该定时任务要具备服务重启后也能执行的能力,本文会详细分析思路,并提供完整实现代码。

思路

  定时任务线程我们使用TimerTask实现。实现思路是写一个接口接收客户端传过来的任务执行时间等参数,然后接口使用TimerTask根据接收到的执行时间参数创建定时任务,并持久化该次任务的任务ID以及执行时间,然后用CommandLineRunner写一个服务启动时执行的任务线程去查询还未执行的定时任务,并使用TimerTask将任务线程重新生成,这样就可以实现服务重启后原定的定时任务也能到点执行。

代码实现

待执行定时任务实体类

import lombok.Data;

@Data
public class CampaignRecordEntity {
    private Long id;

    private String pushTime;

    private Long campaignId;

    private String type;

    private String proxy;
}

接收执行时间参数并持久化待执行任务

// todo 下面这里要记录本次任务的参数内容,并为本次任务请求生成一个任务ID 这里假设任务ID 001
String pushTime = "2024-09-29 18:00:00";// 参数传入的任务执行时刻
String taskId = "001";
Timer timer = new Timer(uuid);
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        try {
        	// todo 下面可以写你待执行任务需要执行的具体内容
        	// 执行完要删除掉任务记录,以免每次重启都查询到任务记录并生成不必要的任务线程
            int deleteRecordNum = browserPushMsgMapper.deleteCampaignRecordByCampaignId(taskId );
            if (deleteRecordNum > 0) {
                log.info("delete campaign record success.");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
};
timer.schedule(task, DateUtils.StringToDate(pushTime, "yyyy-MM-dd HH:mm:ss"));
uuidTimerTaskContainer.put(uuid, task);
CampaignRecordEntity entity = new CampaignRecordEntity();
entity.setCampaignId(e.getId());
entity.setPushTime(pushTime);
int num = mapper.insertCampaignRecord(entity, "Remo");
if (num > 0) {
    log.info("insert campaign record success.");
}

服务启动时待执行任务查询生成

  由于服务重启会导致重启前生成的任务线程被杀死,因此重启后需要重新生成任务线程:

@Slf4j
@Component
@Order(100)
public class SendMsgStartTask implements CommandLineRunner {
    @Resource
    private Mapper mapper;
    
    @Override
    public void run(String... args) throws Exception {
        List<CampaignRecordEntity> records = browserPushMsgMapper.queryCampaignRecords();
        if (records != null && records.size() > 0) {
            for (CampaignRecordEntity entity : records) {
                try {
                    Timer timer = new Timer(UuidUtils.getUuidString(20));
                    String taskId = entity.getId();
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                           	// todo 执行到执行时刻需要执行的内容
                           	// 执行完后要清楚待执行任务
                            int deleteRecordNum = mapper.deleteCampaignRecordByCampaignId(taskId);
                            if (deleteRecordNum > 0) {
                                log.info("delete campaign record success.");
                            }
                        }
                    };
                    timer.schedule(task, DateUtils.StringToDate(DateUtils.millisecondToDate(recordVo.getTime(), "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

http://www.kler.cn/news/332738.html

相关文章:

  • 基于Springboot+Vue的小区停车场管理系统登录(含源码数据库)
  • wsl2 ubuntu 桥接以太网卡
  • git维护【.gitignore文件】
  • Microsoft 更新 Copilot AI,未來將能使用語音並看到你瀏覽的網頁
  • SpringCloud学习记录|day2
  • 手机实时提取SIM卡打电话的信令声音-(题外、插播一条广告)
  • Ubuntu安装Hadoop3.4
  • 书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
  • 常见的VPS或者独立服务器的控制面板推荐
  • 华为云LTS日志上报至观测云最佳实践
  • MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL,如何选择?
  • Kotlin:2.0.20 的新特性
  • 【Spring Security】基于SpringBoot3.3.4版本②如何配置免鉴权Path
  • 昇思学习打卡营第31天|深度解密 CycleGAN 图像风格迁移:从草图到线稿的无缝转化
  • 【AUTOSAR 基础软件】COM模块详解(通信)
  • MATLAB - 机械臂手眼标定(眼在手外) - 估算固定相机相对于机器人基座的姿态
  • Python爬虫通过 Cookie 和会话管理来维持其在网站上的会话状态
  • LeetCode hot100---数组及矩阵专题(C++语言)
  • 15分钟学 Python 第37天 :Python 爬虫入门(三)
  • MATLAB算法实战应用案例精讲-【数模应用】Kaplan Meier(附MATLAB和R语言代码实现)