[Java备忘]定时任务线程池

news/2025/1/17 14:03:53/

定时任务线池备忘

  • 1、定时任务线程池选型
  • 2、ThreadPoolTaskScheduler使用

1、定时任务线程池选型

Java常用的定时任务池方案有:

  1. Java自带

ScheduledExecutorService 、ThreadPoolTaskScheduler。主要区别在于对定时的方式的支持不一样。ThreadPoolTaskScheduler调用还是ScheduledExecutorService。

  1. 框架
    Quartz :Quartz 支持基于日历的作业调度,允许用户创建多个触发器(Trigger)来定义单个作业(Job)的计划。Quartz 也提供了一个基于 JDBC 的存储机制,将作业的配置信息保存在数据库中,以支持分布式部署。Quartz 还具有良好的可扩展性和灵活性,支持集群部署和动态加载作业定义等功能。
    Spring Task:是 Spring 框架提供的一种轻量级的任务调度框架,简化了异步任务的创建和调度过程。Spring Task 支持使用注解配置定时任务,并提供了 CronTrigger 和 SimpleTrigger 等多种触发器类型。可以通过 Spring Task 来执行简单的定时任务,也可以使用它来创建复杂的任务流程和并发作业。

因为短平快,只让部署一台一个应用,使用ScheduledExecutorService够了

2、ThreadPoolTaskScheduler使用

上次使用的是ThreadPoolTaskScheduler方法。

定时任务线程池对象的创建如下,使用单例保证只存在一个定时任务池。

注意多线程下单例问题


import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;/*** 定时任务线程池创建工具类** @since 2022/10/16*/
public class TaskExecutors {/*** 创建定时任务池*/private static final ScheduledExecutorService scheduledThreadPoolExecutor = Executors.newScheduledThreadPool(5);private static final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();static {threadPoolTaskScheduler.setPoolSize(20);threadPoolTaskScheduler.setThreadNamePrefix("CollectSetTaskExecutor-");threadPoolTaskScheduler.initialize();}private TaskExecutors() {}/*** 创建定时任务池(常驻线程)** @return*/@Deprecatedpublic static ScheduledExecutorService getScheduledThreadPool() {return scheduledThreadPoolExecutor;}/*** 创建定时任务池(常驻线程)** @return*/public static ThreadPoolTaskScheduler getThreadPoolTaskScheduler() {return threadPoolTaskScheduler;}
}

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;/*** 定时任务** @since 2022/10/17*/
@Slf4j
@Component
public class CollectSetTask {private final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** key:value 对应* 自定义标识 : thread ScheduleFuture* <p>* 用于存储定时任务状态*/private Map<String, ScheduledFuture> threadMap = new HashMap<>();/*** 执行定时任务,如果定时任务已存在,则清除并重新启动** @param yourTaskObject 信息对象*/public void start(Object yourTaskObject) {String timer = "";String id = "";log.info("Perform tasks immediately at startup:{}", id);// 下面调用schedule方法就是加入定时线程池了,此处作用在于调用本方法后立即执行一次任务new Thread(new YourTaskExecutor(yourTaskObject)).start();// 如果定时任务已存在则清除stopById(id);if (null != threadMap.get(id)) {threadMap.get(id).cancel(true);}// 执行线程并更新状态ScheduledFuture<?> schedule = TaskExecutors.getThreadPoolTaskScheduler().schedule(new YourTaskExecutor(yourTaskObject), new CronTrigger(timer));threadMap.put(id, schedule);log.info("CollectSetTask {} : stars", id);}/*** 停止线程任务** @param request 请求对象*/public void stop(String id) {//获取前端数据log.info("========Start to stop the collectSetTask========");stopById(id);}/*** 依据任务ID停止线程任务** @param id 任务ID*/private void stopById(String id) {if (null != threadMap.get(id)) {threadMap.get(id).cancel(true);}log.info("{} CollectSet task is remove", id);}/*** 任务正在运行返回true,没有在运行返回false** @param id* @return*/public boolean status(String id) {ScheduledFuture scheduledFuture = threadMap.get(id);if (null == scheduledFuture) {return false;}return scheduledFuture.isDone();}/*** 返回所有定时任务状态* 任务正在运行返回true,没有在运行返回false** @return*/public Map<String, Boolean> statusAll() {Set<String> idSet = threadMap.keySet();HashMap<String, Boolean> statusMap = new HashMap<>();for (String id : idSet) {ScheduledFuture scheduledFuture = threadMap.get(id);statusMap.put(id, null != scheduledFuture && !scheduledFuture.isDone());}log.info("当前所有定时任务状态为:{}", JSONUtil.toJsonStr(statusMap));return statusMap;}/*** 采集SQL执行线程*/private class YourTaskExecutor implements Runnable {private Object object;public YourTaskExecutor(Object object) {this.object = object;}/*** 任务线程*/@Overridepublic void run() {log.info("Task {} : is running ", "可以放Object里面的标识");}}
}

http://www.ppmy.cn/news/102042.html

相关文章

重塑工作场所:后疫情时代组织韧性的8个策略

经济寒冬来临&#xff0c;倒挂的收益率曲线、持续上升的利率以及层出不穷的裁员公告等等&#xff0c;让经济学家们得出一个结论&#xff1a;全球经济正在衰退。然而&#xff0c;经济下行周期可能是卓越公司改变其命运的最佳时机。有研究表明&#xff0c;相对于非经济衰退时期&a…

抖音seo源码如何开发部署?

前言&#xff1a;抖音seo源码&#xff0c;抖音矩阵系统源码搭建&#xff0c;抖音矩阵同步分发。抖音seo源码部署是需要对接到这些正规接口再来做开发的&#xff0c;目前账号矩阵程序开发的功能&#xff0c;围绕一键管理多个账号&#xff0c;做到定时投放&#xff0c;关键词自动…

基于AI技术的APP外包开发流程

AI技术发展非常迅速&#xff0c;最近一年有了巨大的技术突破&#xff0c;一些专家认为可以基于现在的AI技术将APP再重做一遍&#xff0c;这无疑将给创业者带来巨大机会。今天和大家分享使用AI重做一个APP的步骤和注意事项&#xff0c;希望对大家有所帮助。 需要遵循以下步骤和注…

如何有效和快速清理C盘

电脑在运行过程中会产生磁盘碎片&#xff0c;时间一长垃圾文件就会越多。而且我们平常不敢乱清理C盘中的文件&#xff0c;以免因为误删导致系统出现故障&#xff0c;所以垃圾文件才肆意占用系统盘空间。不过我们可以选择系统自带的“磁盘清理”功能“制服”它&#xff0c;给C盘…

[答疑]UMLChina的Logo是不是不对劲

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> Lynn 2023-4-6 13:55 潘老师&#xff0c;咱umlchina的标记是不是不太对劲&#xff0c;火柴人指向用例的箭头是三角形似乎不合uml的标准。 UMLChina潘加宇 是的。如果按U…

ERP的需求分析

目录 什么是需求分析? 开发背景 01、系统模块 02、基础资料 供应商信息</

2023年真无线蓝牙耳机买什么品牌好一些?盘点几款值得买的蓝牙耳机

蓝牙耳机是一种无线耳机&#xff0c;其通过蓝牙技术与其他设备进行连接&#xff0c;例如手机、电脑、平板电脑等。蓝牙耳机使得用户可以在不受线缆限制的情况下享受音频体验&#xff0c;而且还可以方便地进行通话&#xff0c;目前市场上有许多不同种类和品牌的蓝牙耳机&#xf…

企业数字化转型,为什么会加快商业智能BI的发展

对于企业数字化转型来说&#xff0c;数据是其中提到最多的词汇。当今世界&#xff0c;随着人们认识到数据的重要性&#xff0c;明白了数据发挥价值的方式及其意义&#xff0c;数据资产就成为数字化转型企业需要掌握利用的关键。 数据可视化 - 派可数据商业智能BI可视化分析平台…