ThreadPoolTaskScheduler手写任务调度

Easter79
• 阅读 721

先贴一个自己写的demo把,原理其实就是这样的。

先记录一个东西,后续来研究:CronSequenceGenerator

报错:Cron expression must consist of 6 fields,这玩意支持6位不支持7位,真是XXXX,quartz支持,参见 https://my.oschina.net/uwith/blog/4395339

CronTrigger这个类可以将cron表达式转换成Date,可以查看schedule源码学到不少东西,下面代码就是转换成下一执行时间。

public Date nextExecutionTime(TriggerContext triggerContext)

@Slf4j @RestController public class HomeController {

_/\*\*

_ * 存储调度器信息_,存在多线程安全问题,__采用__ConcurrentHashMap _ * _初始大小设定大于核心线程池数量__3__倍即可 _ _*/ _ private Map<Integer, ScheduledFuture> map = new ConcurrentHashMap<>(64); ThreadPoolTaskScheduler threadPoolTaskScheduler; public HomeController() { // 注意,此线程池使用DelayedWorkQueue()作为队列,此队列又是基于PriorityQueue, // 自己会根据表达式进行排序,可以查看schedule方法源码以及参数 threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.initialize(); // 线程池需做配置化 threadPoolTaskScheduler.setPoolSize(64); }

@RequestMapping("/home/index/{id}")
public String add(@PathVariable Integer id, @RequestBody String cron) {
    // 添加一个去重复的操作

if (map.containsKey(id)) { return "调度任务已添加成功"; } ScheduledFuture future = threadPoolTaskScheduler.schedule( new Runnable() { @Override public void run() { try { // 触发进行记录日志 StopWatch watch = new StopWatch(); watch.start(); log.info(String.format("%s-调度器已触发,准备rpc调用", id)); // 这里执行具体的操作 Thread.sleep(1000); //执行完成取消 Boolean cancelResult = cancel(id); watch.stop(); log.info(String.format("%s-调度器rpc调用完成,耗时:%s", id, watch.getLastTaskTimeMillis())); } catch (Exception ex) { log.error(String.format("%s-调度器出现异常:%s,堆栈信息:%s", id, ex.getMessage(), ExceptionUtils.getStackTrace(ex))); } } }, new CronTrigger(cron)); // 暂时缓存,用于控制 map.put(id, future); return "调度任务已添加成功"; }

@RequestMapping("/home/cancel/{id}")
public Boolean cancel(@PathVariable Integer id) {
    ScheduledFuture future = map.get(id);

// mayInterruptIfRunning参数指明是否可以中断线程,         // 注意如果写true那么该段代码执行完成,后续操作可能会被中断,比如下面的remove方法,可能执行不到 Boolean result = future.cancel(true); // 然后移除缓存 map.remove(id); return Boolean.TRUE; }

@RequestMapping("/home/query/{id}")
public String query(@PathVariable Integer id) {
    ScheduledFuture future = map.get(id);

StringBuilder sb = new StringBuilder(); sb.append(String.format("future.isCancelled:%s
", future.isCancelled())); sb.append(String.format("future.isDone:%s
", future.isDone())); return sb.toString(); }

@RequestMapping("/home/queryInfo")
public String queryInfo() {
    StringBuilder sb = new StringBuilder();

sb.append(String.format("getPoolSize:%s
", threadPoolTaskScheduler.getPoolSize())); sb.append(String.format("getActiveCount:%s
", threadPoolTaskScheduler.getActiveCount())); sb.append(String.format("getScheduledExecutor.isShutdown", threadPoolTaskScheduler.getScheduledExecutor().isShutdown())); sb.append(String.format("getScheduledExecutor.isTerminated:%s
", threadPoolTaskScheduler.getScheduledExecutor().isTerminated())); sb.append(String.format("getScheduledThreadPoolExecutor.getPoolSize:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getPoolSize())); sb.append(String.format("getScheduledThreadPoolExecutor.getCorePoolSize:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getCorePoolSize())); sb.append(String.format("getScheduledThreadPoolExecutor.getLargestPoolSize:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getLargestPoolSize())); sb.append(String.format("getScheduledThreadPoolExecutor.getMaximumPoolSize:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getMaximumPoolSize())); sb.append(String.format("getScheduledThreadPoolExecutor.getActiveCount:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getActiveCount())); sb.append(String.format("getScheduledThreadPoolExecutor.getTaskCount:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getTaskCount())); sb.append(String.format("getScheduledThreadPoolExecutor.getCompletedTaskCount:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getCompletedTaskCount())); sb.append(String.format("getScheduledThreadPoolExecutor.getQueue:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getQueue().size())); sb.append(String.format("getScheduledThreadPoolExecutor.getKeepAliveTime:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS))); sb.append(String.format("getScheduledThreadPoolExecutor.isShutdown:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().isShutdown())); sb.append(String.format("getScheduledThreadPoolExecutor.isTerminating:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().isTerminating())); sb.append(String.format("getScheduledThreadPoolExecutor.isTerminated:%s
", threadPoolTaskScheduler.getScheduledThreadPoolExecutor().isTerminated())); return sb.toString(); }

}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Souleigh ✨ Souleigh ✨
3年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k