diff --git a/CHANGELOG.md b/CHANGELOG.md index cab105ff7..828a6e32a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * 【system】 增加SystemPropsKeys(issue#550@Github) * 【core】 FileUtil.normalize在win下支持samba路径(issue#549@Github) * 【core】 修复Validator注释错误(pr#70@Gitee) +* 【cron】 添加获取任务表的方法(issue#I12E5H@Gitee) ### Bug修复 * 【core】 修复DateUtil.offset导致的时区错误问题(issue#I1294O@Gitee) diff --git a/README.md b/README.md index 17450f464..591de85d2 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,8 @@ compile 'cn.hutool:hutool-all:4.6.7' Hutool欢迎任何人为Hutool添砖加瓦,贡献代码,不过作者是一个强迫症患者,为了照顾病人,需要提交的pr(pull request)符合一些规范,规范如下: 1. 注释完备,尤其每个新增的方法应按照Java文档规范标明方法说明、参数说明、返回值说明等信息,如果愿意,也可以加上你的大名。 -2. Hutool的缩进按照Eclipse(不要跟我说IDEA多好用,作者非常懒,学不会)默认(tab)缩进,所以请遵守(不要和我争执空格与tab的问题,这是一个病人的习惯)。 +2. Hutool的缩进按照Eclipse(~~不要跟我说IDEA多好用,作者非常懒,学不会~~,IDEA真香,改了Eclipse快捷键后 +舒服多了)默认(tab)缩进,所以请遵守(不要和我争执空格与tab的问题,这是一个病人的习惯)。 3. 新加的方法不要使用第三方库的方法,Hutool遵循无依赖原则(除非在extra模块中加方法工具)。 4. 请pull request到`v4-dev`分支。Hutool在4.x版本后使用了新的分支:`v4-master`是主分支,表示已经发布中央库的版本,这个分支不允许pr,也不允许修改。`v4-dev`分支是开发分支,Hutool的下个版本或者SNAPSHOT版本在这个分支上开发,你可以pr到这个分支。 diff --git a/hutool-cron/src/main/java/cn/hutool/cron/CronException.java b/hutool-cron/src/main/java/cn/hutool/cron/CronException.java index b87be0f9d..504ea90ab 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/CronException.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/CronException.java @@ -7,7 +7,7 @@ import cn.hutool.core.util.StrUtil; * @author xiaoleilu */ public class CronException extends RuntimeException{ - private static final long serialVersionUID = 8247610319171014183L; + private static final long serialVersionUID = 1L; public CronException(Throwable e) { super(e.getMessage(), e); diff --git a/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java b/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java index 2fb350ceb..0bfe6d977 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java @@ -5,15 +5,19 @@ import cn.hutool.core.thread.ThreadUtil; import cn.hutool.log.Log; import cn.hutool.log.LogFactory; +import java.io.Serializable; + /** * 定时任务计时器
* 计时器线程每隔一分钟检查一次任务列表,一旦匹配到执行对应的Task * @author Looly * */ -public class CronTimer extends Thread{ +public class CronTimer extends Thread implements Serializable { + private static final long serialVersionUID = 1L; + private static final Log log = LogFactory.get(); - + /** 定时单元:秒 */ private long TIMER_UNIT_SECOND = DateUnit.SECOND.getMillis(); /** 定时单元:分 */ diff --git a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java index 2b2eccb70..394a4e989 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java @@ -1,5 +1,6 @@ package cn.hutool.cron; +import java.io.Serializable; import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.TimeZone; @@ -51,7 +52,9 @@ import cn.hutool.setting.Setting; * @author Looly * */ -public class Scheduler { +public class Scheduler implements Serializable { + private static final long serialVersionUID = 1L; + private Lock lock = new ReentrantLock(); /** 时区 */ @@ -286,6 +289,16 @@ public class Scheduler { return this; } + /** + * 获取定时任务表,注意此方法返回非复制对象,对返回对象的修改将影响已有定时任务 + * + * @return 定时任务表{@link TaskTable} + * @since 4.6.7 + */ + public TaskTable getTaskTable() { + return this.taskTable; + } + /** * 获得指定id的{@link CronPattern} * diff --git a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java index 61c6bb2f2..0478abbe2 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java @@ -4,28 +4,36 @@ import cn.hutool.cron.task.Task; /** * 作业执行器
- * 执行具体的作业,执行完毕销毁 - * @author Looly + * 执行具体的作业,执行完毕销毁
+ * 作业执行器唯一关联一个作业,负责管理作业的运行的生命周期。 * + * @author Looly */ -public class TaskExecutor implements Runnable{ - +public class TaskExecutor implements Runnable { + private Scheduler scheduler; private Task task; - + /** * 获得任务对象 + * * @return 任务对象 */ public Task getTask() { return task; } + /** + * 构造 + * + * @param scheduler 调度器 + * @param task 被执行的任务 + */ public TaskExecutor(Scheduler scheduler, Task task) { this.scheduler = scheduler; this.task = task; } - + @Override public void run() { try { @@ -34,7 +42,7 @@ public class TaskExecutor implements Runnable{ scheduler.listenerManager.notifyTaskSucceeded(this); } catch (Exception e) { scheduler.listenerManager.notifyTaskFailed(this, e); - }finally{ + } finally { scheduler.taskExecutorManager.notifyExecutorCompleted(this); } } diff --git a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java index 93e2e655a..c3d1308a6 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java @@ -1,6 +1,8 @@ package cn.hutool.cron; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import cn.hutool.cron.task.Task; @@ -8,23 +10,40 @@ import cn.hutool.cron.task.Task; /** * 作业执行管理器
* 负责管理作业的启动、停止等 - * + * + *

+ * 此类用于管理正在运行的作业情况,作业启动后加入任务列表,任务结束移除 + *

+ * * @author Looly * @since 3.0.1 */ -public class TaskExecutorManager { +public class TaskExecutorManager implements Serializable { + private static final long serialVersionUID = 1L; protected Scheduler scheduler; - /** 执行器列表 */ - private List executors = new ArrayList<>(); + /** + * 执行器列表 + */ + private final List executors = new ArrayList<>(); public TaskExecutorManager(Scheduler scheduler) { this.scheduler = scheduler; } /** - * 启动 TaskExecutor - * + * 获取所有正在执行的任务调度执行器 + * + * @return 任务执行器列表 + * @since 4.6.7 + */ + public List getExecutors() { + return Collections.unmodifiableList(this.executors); + } + + /** + * 启动 执行器TaskExecutor,即启动作业 + * * @param task {@link Task} * @return {@link TaskExecutor} */ @@ -41,8 +60,8 @@ public class TaskExecutorManager { } /** - * 执行器执行完毕调用此方法,将执行器从执行器列表移除 - * + * 执行器执行完毕调用此方法,将执行器从执行器列表移除,此方法由{@link TaskExecutor}对象调用,用于通知管理器自身已完成执行 + * * @param executor 执行器 {@link TaskExecutor} * @return this */ @@ -55,7 +74,7 @@ public class TaskExecutorManager { /** * 停止所有TaskExecutor - * + * * @return this * @deprecated 作业执行器只是执行给定的定时任务线程,无法强制关闭,可通过deamon线程方式关闭之 */ diff --git a/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncherManager.java b/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncherManager.java index 5510f6acc..e1c2e3a06 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncherManager.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncherManager.java @@ -1,5 +1,6 @@ package cn.hutool.cron; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -9,11 +10,12 @@ import java.util.List; * @author looly * */ -public class TaskLauncherManager { - +public class TaskLauncherManager implements Serializable { + private static final long serialVersionUID = 1L; + protected Scheduler scheduler; /** 启动器列表 */ - protected List launchers = new ArrayList<>(); + protected final List launchers = new ArrayList<>(); public TaskLauncherManager(Scheduler scheduler) { this.scheduler = scheduler; diff --git a/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java b/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java index 0cf04af09..d5e4b8aef 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java @@ -1,6 +1,9 @@ package cn.hutool.cron; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.TimeZone; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -13,25 +16,25 @@ import cn.hutool.cron.task.Task; * 定时任务表
* 任务表将ID、表达式、任务一一对应,定时任务执行过程中,会周期性检查定时任务表中的所有任务表达式匹配情况,从而执行其对应的任务
* 任务的添加、移除使用读写锁保证线程安全性 - * - * @author Looly * + * @author Looly */ -public class TaskTable { +public class TaskTable implements Serializable { + private static final long serialVersionUID = 1L; private ReadWriteLock lock = new ReentrantReadWriteLock(); private Scheduler scheduler; private TimeZone timezone; - private ArrayList ids = new ArrayList<>(); - private ArrayList patterns = new ArrayList<>(); - private ArrayList tasks = new ArrayList<>(); + private List ids = new ArrayList<>(); + private List patterns = new ArrayList<>(); + private List tasks = new ArrayList<>(); private int size; /** * 构造 - * + * * @param scheduler {@link Scheduler} */ public TaskTable(Scheduler scheduler) { @@ -41,10 +44,10 @@ public class TaskTable { /** * 新增Task - * - * @param id ID + * + * @param id ID * @param pattern {@link CronPattern} - * @param task {@link Task} + * @param task {@link Task} * @return this */ public TaskTable add(String id, CronPattern pattern, Task task) { @@ -64,9 +67,57 @@ public class TaskTable { return this; } + /** + * 获取所有ID,返回不可变列表,即列表不可修改 + * + * @return ID列表 + * @since 4.6.7 + */ + public List getIds() { + final Lock readLock = lock.readLock(); + try { + readLock.lock(); + return Collections.unmodifiableList(this.ids); + } finally { + readLock.unlock(); + } + } + + /** + * 获取所有定时任务表达式,返回不可变列表,即列表不可修改 + * + * @return 定时任务表达式列表 + * @since 4.6.7 + */ + public List getPatterns() { + final Lock readLock = lock.readLock(); + try { + readLock.lock(); + return Collections.unmodifiableList(this.patterns); + } finally { + readLock.unlock(); + } + } + + /** + * 获取所有定时任务,返回不可变列表,即列表不可修改 + * + * @return 定时任务列表 + * @since 4.6.7 + */ + public List getTasks() { + final Lock readLock = lock.readLock(); + try { + readLock.lock(); + return Collections.unmodifiableList(this.tasks); + } finally { + readLock.unlock(); + } + } + /** * 移除Task - * + * * @param id Task的ID */ public void remove(String id) { @@ -84,11 +135,11 @@ public class TaskTable { writeLock.unlock(); } } - + /** * 更新某个Task的定时规则 - * - * @param id Task的ID + * + * @param id Task的ID * @param pattern 新的表达式 * @return 是否更新成功,如果id对应的规则不存在则不更新 * @since 4.0.10 @@ -110,7 +161,7 @@ public class TaskTable { /** * 获得指定位置的{@link Task} - * + * * @param index 位置 * @return {@link Task} * @since 3.1.1 @@ -127,7 +178,7 @@ public class TaskTable { /** * 获得指定id的{@link Task} - * + * * @param id ID * @return {@link Task} * @since 3.1.1 @@ -142,7 +193,7 @@ public class TaskTable { /** * 获得指定位置的{@link CronPattern} - * + * * @param index 位置 * @return {@link CronPattern} * @since 3.1.1 @@ -159,7 +210,7 @@ public class TaskTable { /** * 任务表大小,加入的任务数 - * + * * @return 任务表大小,加入的任务数 * @since 4.0.2 */ @@ -169,7 +220,7 @@ public class TaskTable { /** * 任务表是否为空 - * + * * @return true为空 * @since 4.0.2 */ @@ -179,7 +230,7 @@ public class TaskTable { /** * 获得指定id的{@link CronPattern} - * + * * @param id ID * @return {@link CronPattern} * @since 3.1.1 @@ -194,7 +245,7 @@ public class TaskTable { /** * 如果时间匹配则执行相应的Task,带读锁 - * + * * @param millis 时间毫秒 */ public void executeTaskIfMatch(long millis) { @@ -209,7 +260,7 @@ public class TaskTable { /** * 如果时间匹配则执行相应的Task,无锁 - * + * * @param millis 时间毫秒 * @since 3.1.1 */ diff --git a/hutool-cron/src/main/java/cn/hutool/cron/listener/TaskListenerManager.java b/hutool-cron/src/main/java/cn/hutool/cron/listener/TaskListenerManager.java index 8e29f8926..4556a55dc 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/listener/TaskListenerManager.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/listener/TaskListenerManager.java @@ -1,5 +1,6 @@ package cn.hutool.cron.listener; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -11,8 +12,10 @@ import cn.hutool.log.StaticLog; * @author Looly * */ -public class TaskListenerManager { - private List listeners = new ArrayList<>(); +public class TaskListenerManager implements Serializable { + private static final long serialVersionUID = 1L; + + private final List listeners = new ArrayList<>(); /** * 增加监听器 @@ -45,9 +48,12 @@ public class TaskListenerManager { public void notifyTaskStart(TaskExecutor executor) { synchronized (listeners) { int size = listeners.size(); + TaskListener listener; for (int i = 0; i < size; i++) { - TaskListener listenerl = listeners.get(i); - listenerl.onStart(executor); + listener = listeners.get(i); + if(null != listener){ + listener.onStart(executor); + } } } } diff --git a/hutool-cron/src/main/java/cn/hutool/cron/task/Task.java b/hutool-cron/src/main/java/cn/hutool/cron/task/Task.java index b9ce3e16c..a991ccf1d 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/task/Task.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/task/Task.java @@ -1,14 +1,22 @@ package cn.hutool.cron.task; /** - * 定时作业接口,通过实现execute方法执行具体的任务
- * @author Looly + * 定时作业接口,通过实现execute方法执行具体的任务 + *

+ * 作业执行是异步执行,既不同作业、相同作业在不同时间的执行是相互独立的。
+ * 假如前一个作业未完成,下一个调度开始,则不会等待前一个作业,直接执行。
+ * 关于作业的互斥,请自行加锁完成。 + *

* + * @author Looly */ public interface Task { - + /** * 执行作业 + *

+ * 作业的具体实现需考虑异常情况,默认情况下任务异常在监听中统一监听处理,如果不加入监听,异常会被忽略
+ * 因此最好自行捕获异常后处理 */ public void execute(); }