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文章
4786浏览量
68565 -
spring
+关注
关注
0文章
340浏览量
14341 -
Boot
+关注
关注
0文章
149浏览量
35835 -
SpringBoot
+关注
关注
0文章
173浏览量
177
发布评论请先 登录
相关推荐
关于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
评论