diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3164988b1..247415636 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
-# 5.4.7 (2020-10-29)
+# 5.4.7 (2020-10-31)
### 新特性
* 【core 】 增加OptionalBean(pr#1182@Github)
@@ -13,10 +13,12 @@
* 【http 】 增加SoapClient增加addSOAPHeader重载
* 【http 】 ArrayUtil增加containsAll方法
* 【http 】 增加CharsetDetector
+* 【cron 】 增加CronTask,监听支持获取id(issue#I23315@Gitee)
### Bug修复
* 【core 】 修复BeanUtil.beanToMap方法中editor返回null没有去掉的问题
* 【core 】 修复ImgUtil.toBufferedImage颜色模式的问题(issue#1194@Github)
+* 【cron 】 修复TimeZone设置无效的问题(issue#I23315@Gitee)
-------------------------------------------------------------------------------------------------------------
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java b/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java
new file mode 100644
index 000000000..cbb3a7713
--- /dev/null
+++ b/hutool-cron/src/main/java/cn/hutool/cron/CronConfig.java
@@ -0,0 +1,64 @@
+package cn.hutool.cron;
+
+import java.util.TimeZone;
+
+/**
+ * 定时任务配置类
+ *
+ * @author looly
+ * @since 5.4.7
+ */
+public class CronConfig {
+
+ /**
+ * 时区
+ */
+ protected TimeZone timezone = TimeZone.getDefault();
+ /**
+ * 是否支持秒匹配
+ */
+ protected boolean matchSecond;
+
+ public CronConfig(){
+ }
+
+ /**
+ * 设置时区
+ *
+ * @param timezone 时区
+ * @return this
+ */
+ public CronConfig setTimeZone(TimeZone timezone) {
+ this.timezone = timezone;
+ return this;
+ }
+
+ /**
+ * 获得时区,默认为 {@link TimeZone#getDefault()}
+ *
+ * @return 时区
+ */
+ public TimeZone getTimeZone() {
+ return this.timezone;
+ }
+
+ /**
+ * 是否支持秒匹配
+ *
+ * @return true
使用,false
不使用
+ */
+ public boolean isMatchSecond() {
+ return this.matchSecond;
+ }
+
+ /**
+ * 设置是否支持秒匹配,默认不使用
+ *
+ * @param isMatchSecond true
支持,false
不支持
+ * @return this
+ */
+ public CronConfig setMatchSecond(boolean isMatchSecond) {
+ this.matchSecond = isMatchSecond;
+ return this;
+ }
+}
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 abc95544c..d25c92add 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/CronTimer.java
@@ -37,7 +37,7 @@ public class CronTimer extends Thread implements Serializable {
@Override
public void run() {
- final long timerUnit = this.scheduler.matchSecond ? TIMER_UNIT_SECOND : TIMER_UNIT_MINUTE;
+ final long timerUnit = this.scheduler.config.matchSecond ? TIMER_UNIT_SECOND : TIMER_UNIT_MINUTE;
long thisTime = System.currentTimeMillis();
long nextTime;
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 b9a925800..ed0e78d33 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java
@@ -57,19 +57,17 @@ public class Scheduler implements Serializable {
private final Lock lock = new ReentrantLock();
- /** 时区 */
- private TimeZone timezone;
+ /** 定时任务配置 */
+ protected CronConfig config = new CronConfig();
/** 是否已经启动 */
private boolean started = false;
- /** 是否支持秒匹配 */
- protected boolean matchSecond = false;
/** 是否为守护线程 */
protected boolean daemon;
/** 定时器 */
private CronTimer timer;
/** 定时任务表 */
- protected TaskTable taskTable = new TaskTable(this);
+ protected TaskTable taskTable = new TaskTable();
/** 启动器管理器 */
protected TaskLauncherManager taskLauncherManager;
/** 执行器管理器 */
@@ -83,11 +81,11 @@ public class Scheduler implements Serializable {
/**
* 设置时区
*
- * @param timezone 时区
+ * @param timeZone 时区
* @return this
*/
- public Scheduler setTimeZone(TimeZone timezone) {
- this.timezone = timezone;
+ public Scheduler setTimeZone(TimeZone timeZone) {
+ this.config.setTimeZone(timeZone);
return this;
}
@@ -97,7 +95,7 @@ public class Scheduler implements Serializable {
* @return 时区
*/
public TimeZone getTimeZone() {
- return timezone != null ? timezone : TimeZone.getDefault();
+ return this.config.getTimeZone();
}
/**
@@ -136,7 +134,7 @@ public class Scheduler implements Serializable {
* @return true
使用,false
不使用
*/
public boolean isMatchSecond() {
- return this.matchSecond;
+ return this.config.isMatchSecond();
}
/**
@@ -146,7 +144,7 @@ public class Scheduler implements Serializable {
* @return this
*/
public Scheduler setMatchSecond(boolean isMatchSecond) {
- this.matchSecond = isMatchSecond;
+ this.config.setMatchSecond(isMatchSecond);
return this;
}
@@ -347,7 +345,7 @@ public class Scheduler implements Serializable {
* @since 4.1.17
*/
public Scheduler clear() {
- this.taskTable = new TaskTable(this);
+ this.taskTable = new TaskTable();
return this;
}
// -------------------------------------------------------------------- shcedule end
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 5365751f0..f74a4f15f 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutor.java
@@ -1,5 +1,6 @@
package cn.hutool.cron;
+import cn.hutool.cron.task.CronTask;
import cn.hutool.cron.task.Task;
/**
@@ -12,15 +13,25 @@ import cn.hutool.cron.task.Task;
public class TaskExecutor implements Runnable {
private final Scheduler scheduler;
- private final Task task;
+ private final CronTask task;
/**
- * 获得任务对象
+ * 获得原始任务对象
*
* @return 任务对象
*/
public Task getTask() {
- return task;
+ return this.task.getRaw();
+ }
+
+ /**
+ * 获得原始任务对象
+ *
+ * @return 任务对象
+ * @since 5.4.7
+ */
+ public CronTask getCronTask() {
+ return this.task;
}
/**
@@ -29,7 +40,7 @@ public class TaskExecutor implements Runnable {
* @param scheduler 调度器
* @param task 被执行的任务
*/
- public TaskExecutor(Scheduler scheduler, Task task) {
+ public TaskExecutor(Scheduler scheduler, CronTask task) {
this.scheduler = scheduler;
this.task = task;
}
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 c3d1308a6..09a06eb2a 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskExecutorManager.java
@@ -1,12 +1,13 @@
package cn.hutool.cron;
+import cn.hutool.cron.task.CronTask;
+import cn.hutool.cron.task.Task;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import cn.hutool.cron.task.Task;
-
/**
* 作业执行管理器
* 负责管理作业的启动、停止等
@@ -47,7 +48,7 @@ public class TaskExecutorManager implements Serializable {
* @param task {@link Task}
* @return {@link TaskExecutor}
*/
- public TaskExecutor spawnExecutor(Task task) {
+ public TaskExecutor spawnExecutor(CronTask task) {
final TaskExecutor executor = new TaskExecutor(this.scheduler, task);
synchronized (this.executors) {
this.executors.add(executor);
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncher.java b/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncher.java
index 675ae8576..5b85c277f 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncher.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskLauncher.java
@@ -12,7 +12,13 @@ public class TaskLauncher implements Runnable{
private final Scheduler scheduler;
private final long millis;
-
+
+ /**
+ * 构造
+ *
+ * @param scheduler {@link Scheduler}
+ * @param millis 毫秒数
+ */
public TaskLauncher(Scheduler scheduler, long millis) {
this.scheduler = scheduler;
this.millis = millis;
@@ -21,7 +27,7 @@ public class TaskLauncher implements Runnable{
@Override
public void run() {
//匹配秒部分由用户定义决定,始终不匹配年
- scheduler.taskTable.executeTaskIfMatchInternal(millis);
+ scheduler.taskTable.executeTaskIfMatch(this.scheduler, this.millis);
//结束通知
scheduler.taskLauncherManager.notifyLauncherCompleted(this);
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 27daf2948..517db1ebd 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/TaskTable.java
@@ -1,13 +1,13 @@
package cn.hutool.cron;
import cn.hutool.cron.pattern.CronPattern;
+import cn.hutool.cron.task.CronTask;
import cn.hutool.cron.task.Task;
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;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -22,24 +22,33 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TaskTable implements Serializable {
private static final long serialVersionUID = 1L;
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ public static final int DEFAULT_CAPACITY = 10;
- private final Scheduler scheduler;
- private final TimeZone timezone;
+ private final ReadWriteLock lock;
- private final List ids = new ArrayList<>();
- private final List patterns = new ArrayList<>();
- private final List tasks = new ArrayList<>();
+ private final List ids;
+ private final List patterns;
+ private final List tasks;
private int size;
/**
* 构造
- *
- * @param scheduler {@link Scheduler}
*/
- public TaskTable(Scheduler scheduler) {
- this.scheduler = scheduler;
- this.timezone = scheduler.getTimeZone();
+ public TaskTable() {
+ this(DEFAULT_CAPACITY);
+ }
+
+ /**
+ * 构造
+ *
+ * @param initialCapacity 容量,即预估的最大任务数
+ */
+ public TaskTable(int initialCapacity) {
+ lock = new ReentrantReadWriteLock();
+
+ ids = new ArrayList<>(initialCapacity);
+ patterns = new ArrayList<>(initialCapacity);
+ tasks = new ArrayList<>(initialCapacity);
}
/**
@@ -246,13 +255,14 @@ public class TaskTable implements Serializable {
/**
* 如果时间匹配则执行相应的Task,带读锁
*
+ * @param scheduler {@link Scheduler}
* @param millis 时间毫秒
*/
- public void executeTaskIfMatch(long millis) {
+ public void executeTaskIfMatch(Scheduler scheduler, long millis) {
final Lock readLock = lock.readLock();
readLock.lock();
try {
- executeTaskIfMatchInternal(millis);
+ executeTaskIfMatchInternal(scheduler, millis);
} finally {
readLock.unlock();
}
@@ -261,14 +271,15 @@ public class TaskTable implements Serializable {
/**
* 如果时间匹配则执行相应的Task,无锁
*
+ * @param scheduler {@link Scheduler}
* @param millis 时间毫秒
* @since 3.1.1
*/
- protected void executeTaskIfMatchInternal(long millis) {
+ protected void executeTaskIfMatchInternal(Scheduler scheduler, long millis) {
for (int i = 0; i < size; i++) {
- if (patterns.get(i).match(timezone, millis, this.scheduler.matchSecond)) {
- this.scheduler.taskExecutorManager.spawnExecutor(tasks.get(i));
+ if (patterns.get(i).match(scheduler.config.timezone, millis, scheduler.config.matchSecond)) {
+ scheduler.taskExecutorManager.spawnExecutor(new CronTask(ids.get(i), patterns.get(i), tasks.get(i)));
}
}
}
-}
+}
\ No newline at end of file
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 ff2f5502c..e326f9472 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
@@ -65,8 +65,8 @@ public class TaskListenerManager implements Serializable {
public void notifyTaskSucceeded(TaskExecutor executor) {
synchronized (listeners) {
int size = listeners.size();
- for (TaskListener listenerl : listeners) {
- listenerl.onSucceeded(executor);
+ for (TaskListener listener : listeners) {
+ listener.onSucceeded(executor);
}
}
}
diff --git a/hutool-cron/src/main/java/cn/hutool/cron/task/CronTask.java b/hutool-cron/src/main/java/cn/hutool/cron/task/CronTask.java
new file mode 100644
index 000000000..c3442a378
--- /dev/null
+++ b/hutool-cron/src/main/java/cn/hutool/cron/task/CronTask.java
@@ -0,0 +1,70 @@
+package cn.hutool.cron.task;
+
+import cn.hutool.cron.pattern.CronPattern;
+
+/**
+ * 定时作业,此类除了定义了作业,也定义了作业的执行周期以及ID。
+ *
+ * @author looly
+ * @since 5.4.7
+ */
+public class CronTask implements Task{
+
+ private final String id;
+ private CronPattern pattern;
+ private final Task task;
+
+ /**
+ * 构造
+ * @param id ID
+ * @param pattern 表达式
+ * @param task 作业
+ */
+ public CronTask(String id, CronPattern pattern, Task task) {
+ this.id = id;
+ this.pattern = pattern;
+ this.task = task;
+ }
+
+ @Override
+ public void execute() {
+ task.execute();
+ }
+
+ /**
+ * 获取作业ID
+ *
+ * @return 作业ID
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * 获取表达式
+ *
+ * @return 表达式
+ */
+ public CronPattern getPattern() {
+ return pattern;
+ }
+
+ /**
+ * 设置新的定时表达式
+ * @param pattern 表达式
+ * @return this
+ */
+ public CronTask setPattern(CronPattern pattern){
+ this.pattern = pattern;
+ return this;
+ }
+
+ /**
+ * 获取原始作业
+ *
+ * @return 作业
+ */
+ public Task getRaw(){
+ return this.task;
+ }
+}
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 1db81a88f..ca2b77deb 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
@@ -10,6 +10,7 @@ package cn.hutool.cron.task;
*
* @author Looly
*/
+@FunctionalInterface
public interface Task {
/**
diff --git a/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java b/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
index 569e54cd4..33e94f552 100644
--- a/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
+++ b/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
@@ -22,6 +22,9 @@ public class CronTest {
// 支持秒级别定时任务
CronUtil.setMatchSecond(true);
CronUtil.start();
+
+ ThreadUtil.waitForDie();
+ Console.log("Exit.");
}
@Test
@@ -32,27 +35,27 @@ public class CronTest {
CronUtil.getScheduler().setDaemon(false);
CronUtil.start();
- ThreadUtil.sleep(3000);
+ ThreadUtil.waitForDie();
CronUtil.stop();
}
@Test
@Ignore
- public void cronTest2() {
+ public void cronWithListenerTest() {
CronUtil.getScheduler().addListener(new TaskListener() {
@Override
public void onStart(TaskExecutor executor) {
- Console.log("Listen task start!");
+ Console.log("Found task:[{}] start!", executor.getCronTask().getId());
}
@Override
public void onSucceeded(TaskExecutor executor) {
-
+ Console.log("Found task:[{}] success!", executor.getCronTask().getId());
}
@Override
public void onFailed(TaskExecutor executor, Throwable exception) {
-
+ Console.error("Found task:[{}] failed!", executor.getCronTask().getId());
}
});
@@ -65,7 +68,7 @@ public class CronTest {
}
@Test
-// @Ignore
+ @Ignore
public void addAndRemoveTest() {
String id = CronUtil.schedule("*/2 * * * * *", (Runnable) () -> Console.log("task running : 2s"));