上传备份

master
王兵 3 weeks ago
parent c779c3fb0b
commit 64f9b0f813

@ -1,7 +1,6 @@
package xyz.wbsite.jmacro; package xyz.wbsite.jmacro;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import org.jobrunr.jobs.lambdas.JobLambda;
import xyz.wbsite.jmacro.base.Legend; import xyz.wbsite.jmacro.base.Legend;
import xyz.wbsite.jmacro.util.DialogUtil; import xyz.wbsite.jmacro.util.DialogUtil;
import xyz.wbsite.jmacro.util.Logger; import xyz.wbsite.jmacro.util.Logger;

@ -3,9 +3,13 @@ package xyz.wbsite.jmacro;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
@ -31,88 +35,108 @@ public class JScheduler {
/** /**
* ID ScheduledFuture<?> * ID ScheduledFuture<?>
*/ */
private final Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>(); private final Queue<ScheduledFuture<?>> tasksHolder = new ConcurrentLinkedQueue<>();
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
/** /**
* *
* *
* @param taskId ID
* @param task * @param task
* @param initialDelay * @param intervalSeconds
* @param delay
* @param unit
*/ */
public void scheduleFixedDelay(String taskId, Runnable task, long initialDelay, long delay, TimeUnit unit) { public void schedule(Runnable task, long intervalSeconds) {
cancelTask(taskId); ScheduledFuture<?> future = executor.scheduleWithFixedDelay(task, 0, intervalSeconds, TimeUnit.SECONDS);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(task, initialDelay, delay, unit); tasksHolder.add(future);
tasks.put(taskId, future);
} }
/** /**
* *
* *
* @param taskId ID
* @param task * @param task
* @param initialDelay * @param intervalSeconds
* @param period
* @param unit
* @param times * @param times
*/ */
public void scheduleFixedTimes(String taskId, Runnable task, long initialDelay, long period, TimeUnit unit, int times) { public void schedule(Runnable task, long intervalSeconds, int times) {
cancelTask(taskId); ScheduledFuture<?> future = executor.scheduleWithFixedDelay(new LimitedTask(task, times), 0, intervalSeconds, TimeUnit.SECONDS);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(new LimitedTask(task, times), initialDelay, period, unit); tasksHolder.add(future);
tasks.put(taskId, future);
} }
private final Map<Runnable, ConcurrentSkipListSet<Integer>> taskTimeMap = new ConcurrentHashMap<>();
/** /**
* "08:30:00,12:00:00,18:00:00" *
* *
* @param taskId ID * @param task
* @param task * @param time
* @param timePoints
*/ */
public void scheduleAtTimes(String taskId, Runnable task, String timePoints) { public void schedule(Runnable task, String time) {
cancelTask(taskId); schedule(task, Arrays.asList(time.split(",")));
}
List<LocalTime> times = parseTimePoints(timePoints); /**
if (times.isEmpty()) return; *
* <p>
* "08:30:00"
*
* @param task
* @param time
*/
public void schedule(Runnable task, List<String> time) {
if (time.isEmpty()) {
return;
}
Runnable timeChecker = () -> { // 转换为数字集合(秒级精度)
LocalTime now = LocalTime.now(); ConcurrentSkipListSet<Integer> timeSet = new ConcurrentSkipListSet<>();
for (LocalTime scheduledTime : times) { Runnable trigger = () -> {
if (isSameTime(now, scheduledTime)) { for (String string : time) {
task.run(); int nowSeconds = LocalTime.now().toSecondOfDay();
int secondOfDay = LocalTime.parse(string, TIME_FORMATTER).toSecondOfDay();
if (secondOfDay < nowSeconds) {
continue;
} }
timeSet.add(secondOfDay);
} }
}; };
trigger.run();
// 每秒检查一次 // 修正时间计算:计算到下一个凌晨的秒数
ScheduledFuture<?> future = executor.scheduleAtFixedRate(timeChecker, 0, 1, TimeUnit.SECONDS); long nowSeconds = LocalTime.now().toSecondOfDay();
tasks.put(taskId, future); // 剩余秒数到次日凌晨
long delay = (24 * 3600 - nowSeconds) % (24 * 3600);
// 使用 scheduleAtFixedRate 保证每日执行
ScheduledFuture<?> triggerFuture = executor.scheduleAtFixedRate(
trigger,
delay,
24 * 3600, // 24小时周期
TimeUnit.SECONDS
);
tasksHolder.add(triggerFuture);
// 创建每秒检查的任务
Runnable checker = () -> {
int now = LocalTime.now().toSecondOfDay();
Integer nextTime = timeSet.floor(now);
if (nextTime != null) {
task.run();
timeSet.remove(nextTime);
} }
};
/** ScheduledFuture<?> checkerFuture = executor.scheduleAtFixedRate(checker, 0, 1, TimeUnit.SECONDS);
* tasksHolder.add(checkerFuture);
*/
public void cancelAllTask() {
for (ScheduledFuture<?> future : tasks.values()) {
future.cancel(false);
}
tasks.clear();
} }
/** /**
* *
*
* @param taskId ID
*/ */
public void cancelTask(String taskId) { public void cancel() {
ScheduledFuture<?> future = tasks.remove(taskId); for (ScheduledFuture<?> future : tasksHolder) {
if (future != null) {
future.cancel(false); future.cancel(false);
} }
tasksHolder.clear();
} }
/** /**
@ -130,7 +154,9 @@ public class JScheduler {
*/ */
private List<LocalTime> parseTimePoints(String timePoints) { private List<LocalTime> parseTimePoints(String timePoints) {
List<LocalTime> result = new ArrayList<>(); List<LocalTime> result = new ArrayList<>();
if (timePoints == null || timePoints.trim().isEmpty()) return result; if (timePoints == null || timePoints.trim().isEmpty()) {
return result;
}
String[] parts = timePoints.split(","); String[] parts = timePoints.split(",");
for (String part : parts) { for (String part : parts) {
@ -143,19 +169,6 @@ public class JScheduler {
return result; return result;
} }
/**
*
*
* @param t1 1
* @param t2 2
* @return
*/
private boolean isSameTime(LocalTime t1, LocalTime t2) {
return t1.getHour() == t2.getHour() &&
t1.getMinute() == t2.getMinute() &&
t1.getSecond() == t2.getSecond();
}
/** /**
* *
*/ */
@ -175,9 +188,9 @@ public class JScheduler {
remainingTimes--; remainingTimes--;
if (remainingTimes == 0) { if (remainingTimes == 0) {
// 任务执行完毕,取消自己 // 任务执行完毕,取消自己
for (Map.Entry<String, ScheduledFuture<?>> entry : tasks.entrySet()) { for (ScheduledFuture<?> future : tasksHolder) {
if (entry.getValue().isDone()) { if (future.isDone()) {
tasks.remove(entry.getKey()); tasksHolder.remove(future);
} }
} }
} }
@ -189,28 +202,27 @@ public class JScheduler {
JScheduler scheduler = new JScheduler(); JScheduler scheduler = new JScheduler();
// 1. 无限循环任务每2秒执行一次 // 1. 无限循环任务每2秒执行一次
scheduler.scheduleFixedDelay("task1", // scheduler.schedule(() -> System.out.println("无限任务执行: " + LocalTime.now()),
() -> System.out.println("无限任务执行: " + LocalTime.now()), // 2);
0, 2, TimeUnit.SECONDS);
// // 2. 有限次数任务执行5次每1秒一次
// 2. 有限次数任务执行5次每1秒一次 // scheduler.schedule(
scheduler.scheduleFixedTimes("task2", // () -> System.out.println("有限任务执行: " + LocalTime.now()),
() -> System.out.println("有限任务执行: " + LocalTime.now()), // 3, 5);
0, 1, TimeUnit.SECONDS, 5); //
// // 3. 多时间点任务(每天 08:30:00, 12:00:00, 18:00:00 执行)
// 3. 多时间点任务(每天 08:30:00, 12:00:00, 18:00:00 执行) scheduler.schedule(
scheduler.scheduleAtTimes("task3",
() -> System.out.println("定时任务执行: " + LocalTime.now()), () -> System.out.println("定时任务执行: " + LocalTime.now()),
"08:30:00,12:00:00,18:00:00"); "12:58:00,18:00:00");
// 运行一段时间后关闭 // 运行一段时间后关闭
try { try {
Thread.sleep(10_000); Thread.sleep(60_000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
scheduler.cancelAllTask(); scheduler.cancel();
scheduler.shutdown(); scheduler.shutdown();
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.