SchedulingConfigurer 接口只能统一修改,要分开控制的话有多少个job就要有多少个实现。比较麻烦

配置线程池ThreadPoolTaskScheduler

@Configuration
public class JobConfig {
@Bean("taskExecutor")
public ThreadPoolTaskScheduler taskExecutor() {
ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
executor.setPoolSize(20);
executor.setThreadNamePrefix("taskExecutor-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(300);
return executor;
}
}

封装实现

@Component
@Slf4j
public class Jobs {
/**
* key josId
* value ScheduledFuture object
*/
private final ConcurrentHashMap<Integer, ScheduledFuture> jobsMap = new ConcurrentHashMap<>(8); private final ApplicationContext applicationContext;
private final ThreadPoolTaskScheduler threadPoolTaskScheduler;
private final EcoScheduleJobMapper scheduleJobMapper; public Jobs(ApplicationContext applicationContext, EcoScheduleJobMapper scheduleJobMapper, ThreadPoolTaskScheduler threadPoolTaskScheduler) {
this.applicationContext = applicationContext;
this.scheduleJobMapper = scheduleJobMapper;
this.threadPoolTaskScheduler = threadPoolTaskScheduler;
init();
} public Map<Integer, ScheduledFuture> getJobsMap() {
return jobsMap;
} public void start(Integer jobId) {
if (jobsMap.containsKey(jobId)) {
log.debug("job:{} is running", jobId);
// running...
return;
} executeJob(selectJobsDetail(jobId));
} public void stop(Integer jobId) {
ScheduledFuture scheduledFuture = jobsMap.get(jobId);
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
log.debug("job cancel:{}", scheduledFuture);
} else
log.debug("jobId:{} is not running ", jobId);
} private EcoScheduleJob selectJobsDetail(Integer jobId) {
return scheduleJobMapper.selectByPrimaryKey(jobId);
} // 修改corn配置,先取消再重新启动
public void reset(Integer jobId) {
ScheduledFuture scheduledFuture = jobsMap.get(jobId);
EcoScheduleJob scheduleJob = selectJobsDetail(jobId);
if (Objects.nonNull(scheduledFuture)) {
scheduledFuture.cancel(true);
log.debug("job:{} cancel success", scheduleJob);
}
if (Objects.nonNull(scheduleJob)) {
executeJob(scheduleJob);
log.debug("job:{} start success", scheduleJob);
}
} // 启动初始化启动所有job
private void init() {
// 从数据库获取任务信息
List<EcoScheduleJob> jobs = scheduleJobMapper.selectJobs();
if (CollectionUtils.isNotEmpty(jobs)) {
jobs.forEach(this::executeJob);
}
} private void executeJob(EcoScheduleJob job) {
Runnable runnable = null;
try {
Class<?> clazz = Class.forName(job.getClassName());
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
if (!Arrays.isNullOrEmpty(declaredConstructors)) {
// 只取一个构造器
if (declaredConstructors.length > 1) {
log.warn("{} 存在多个构造器,只能有一个", clazz);
return;
}
Constructor<?> constructor = declaredConstructors[0];
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 0) {
log.warn("{} 无参构造器", clazz);
return;
}
Class<?> parameterType = parameterTypes[0];
Object bean = applicationContext.getBean(parameterType);
runnable = (Runnable) constructor.newInstance(bean);
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
log.error("任务调度失败:{}", e);
}
if (Objects.nonNull(runnable)) {
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(job.getCron()));
jobsMap.put(job.getJobId(), schedule);
log.debug("job:{} is running...", job);
} else {
log.error("任务调度失败 job Class is null");
}
} }

pojo

@Table(name = "`eco_schedule_job`")
@Data
public class EcoScheduleJob implements Serializable {
/**
* pk
*/
@Id
@Column(name = "`job_id`")
private Integer jobId; /**
* 类名
*/
@Column(name = "`class_name`")
private String className; /**
* cron表达式
*/
@Column(name = "`cron`")
private String cron; /**
* 状态 1 停用 0 启动
*/
@Column(name = "`status`")
private String status;
}

controller

@RequestMapping("/job")
@RestController
public class ScheduleJobController { @Reference
private ScheduleJobService scheduleJobService; @GetMapping("/status.do")
public Object status() {
return scheduleJobService.status();
} @GetMapping("/start.do")
public Object start(@RequestParam Integer jobId) {
scheduleJobService.start(jobId);
return Response.OK();
} @GetMapping("/stop.do")
public Object stop(@RequestParam Integer jobId) {
scheduleJobService.stop(jobId);
return Response.OK();
} @GetMapping("/update.do")
public Object update(@RequestParam Integer jobId, @RequestParam String cron) {
scheduleJobService.update(jobId, cron);
return Response.OK();
}
}

service

@Service
public class ScheduleJobServiceImpl implements ScheduleJobService { private final EcoScheduleJobMapper ecoScheduleJobMapper; private final Jobs jobs; public ScheduleJobServiceImpl(EcoScheduleJobMapper ecoScheduleJobMapper , Jobs jobs) {
this.ecoScheduleJobMapper = ecoScheduleJobMapper;
this.jobs = jobs;
} @Override
public void update(Integer jobId, String cron) {
EcoScheduleJob scheduleJob = new EcoScheduleJob();
scheduleJob.setJobId(jobId);
scheduleJob.setCron(cron);
ecoScheduleJobMapper.updateByPrimaryKeySelective(scheduleJob); jobs.reset(jobId);
} @Override
public void stop(Integer jobId) {
jobs.stop(jobId);
} @Override
public void start(Integer jobId) {
jobs.start(jobId);
} @Override
public List<EcoScheduleJob> status() {
Set<Integer> integers = jobs.getJobsMap().keySet();
String join = StringUtils.join(integers, ",");
return ecoScheduleJobMapper.selectByIds(join);
}
}

使用ThreadPoolTaskScheduler动态修改调度时间的更多相关文章

  1. Python任务调度模块 – APScheduler。动态修改调度时间间隔

    APScheduler可以把调度任务放到内存里,也可以把任务放到数据库里,那么如何交互式修改定时任务的执行时间间隔或者下次执行时间呢? 方案一:把定时任务放到数据库里,修改数据库里任务的调度时间 方案 ...

  2. 动态修改Spring定时器

    spring 的Quartz定时器的功能非常强大,可以在特定的年月日小时分秒的时间点触发时间,完成事件的调度,就像windows中得计划任务一样.下面看一个典型的Quartz定时器的实现:   1.首 ...

  3. Quartz动态改变任务时间

    基于quartz-2.2 的动态任务调度 Quartz是一个完全由java编写的开源作业调度框架. 调度器 Quartz框架的核心是调度器.调度器负责管理Quartz应用运行时环境.调度器不是靠自己做 ...

  4. ArcGIS Server 10.2 实战(二)动态修改要素数据的地理处理服务

    上一篇<ArcGIS Server 10.2 实战(一)Asp.net MVC与JSON数据妙用实现动态生成要素图层>介绍了如何用JSON转要素的地理处理服务,实现了动态创建点要素并加载到 ...

  5. 动态修改 C 语言函数的实现

    Objective-C 作为基于 Runtime 的语言,它有非常强大的动态特性,可以在运行期间自省.进行方法调剂.为类增加属性.修改消息转发链路,在代码运行期间通过 Runtime 几乎可以修改 O ...

  6. Unity 3D动态修改Shader状态,使物体透明等等

    Unity动态改Shader状态透明 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  7. Linux ulimit和动态修改MySQL最大线程数限制

    ulimit是限制进程对资源的使用但软件资源限制变化不大,特别是process/file,分别对应nproc和nofilenproc可用 ulimit -u 查询:nofile可用 ulimit -n ...

  8. Kafka Java consumer动态修改topic订阅

    前段时间在Kafka QQ群中有人问及此事——关于Java consumer如何动态修改topic订阅的问题.仔细一想才发现这的确是个好问题,因为如果简单地在另一个线程中直接持有consumer实例然 ...

  9. log4j2动态修改日志级别及拓展性使用

    一.供参考的完整日志配置 <?xml version="1.0" encoding="UTF-8"?> <!-- 配置LoggerConfig ...

随机推荐

  1. CSS基本样式-文本属性

    字体属性 文本属性呢,自我认为就是写文档的一些格式属性,例如:字体颜色,字体加粗,字体大小,字体类型等,而且我们在输出测试用例报告的时候也可以用到这些属性,对测试报告进行优化. <html> ...

  2. zabbix监控java

    参考: 官网: https://www.zabbix.com/documentation/4.0/manual/config/items/itemtypes/jmx_monitoring

  3. CDH的ntp时间同步

    云服务器: ntpq -p ntpdate -u 10.52.255.1  #手动同步 自建NTP服务器: https://www.cnblogs.com/yinzhengjie/p/9480665. ...

  4. [转帖]什么是 LLVM?Swift, Rust, Clang 等语言背后的支持

    要了解用于以编程方式生成机器原生代码的编译器框架是如何让新语言的推出以及对现有的语言进行增强比以往更加容易了. https://www.oschina.net/translate/what-is-ll ...

  5. POJ 2995 Brackets 区间DP

    POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...

  6. 2017年0406------如何使用sessionStroage来储存参数是对象的,以及localStorage和sessionStorage的不同地方

    由于项目需要,需要向另外个页面传参数,,由于参数比较特殊,是对象,所以需要用到sessionStorage方法,下面简单的总结一下方法: (1)这个是要将对象转换成字符串,再存储到storage中, ...

  7. 教你搭建基于typescript的vue项目

    自尤大去年9月推出vue对typescript的支持后,一直想开箱尝试,对于前端sr来说,vue的顺滑加上ts的面向对象,想着就非常美好~ 终于在两个月前,找到了个机会尝试了一把vue+ts的组合. ...

  8. Java学习路线(完整详细版)

    Java学习路线(完整详细版) https://jingyan.baidu.com/article/c1a3101e110864de656deb83.html

  9. java 约瑟夫问题

    题目: 给定一个数组及数组的长度,另外给定一个数m,从数组的第一个元素出发,数到第m个元素出列(如果到最后则回到第一个元素).出列元素的值作为m的新值,从出列元素的下一元素继续开始数下去,直到所有元素 ...

  10. pycharm使用已经配置好的virtualenv环境

    前面已经介绍过基本的virtualenv使用方法,如想要了解的同学可以跳转https://www.cnblogs.com/weilijie/p/10964872.html 下面进入正题,我使用的是py ...