Map<定时多久,List<方法>> map 动态定时任务
需求
使用一个结构来管理定时任务,其中每个时间间隔对应一组方法。这些方法需要在指定的时间间隔内执行。具体来说,维护一个 Map
,键是定时的间隔(以秒为单位),值是需要在这些间隔内执行的方法列表。
解决方案
- 定义一个
TaskScheduler
类,它可以维护一个Map<Long, List<Runnable>>
,其中Long
是间隔时间(秒),List<Runnable>
是在该时间间隔内执行的方法列表。 - 动态调度任务,根据时间间隔启动定时任务,并确保每个时间间隔内的所有方法都能被执行。
代码实现
1. DynamicTaskScheduler.java
- 动态调度类
package com.example.scheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ScheduledFuture;
@Component
public class DynamicTaskScheduler {
private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
private final Map<Long, List<Runnable>> tasksMap = new HashMap<>();
private final Map<Long, ScheduledFuture<?>> scheduledTasks = new HashMap<>();
@PostConstruct
public void init() {
taskScheduler.setPoolSize(5); // 设定线程池大小
taskScheduler.initialize();
}
// 添加任务到指定时间间隔
public void addTask(long intervalInSeconds, Runnable task) {
tasksMap.computeIfAbsent(intervalInSeconds, k -> new ArrayList<>()).add(task);
}
// 启动所有定时任务
public void startAllTasks() {
for (Map.Entry<Long, List<Runnable>> entry : tasksMap.entrySet()) {
long interval = entry.getKey();
List<Runnable> tasks = entry.getValue();
// 取消已有任务
if (scheduledTasks.containsKey(interval) && scheduledTasks.get(interval) != null) {
scheduledTasks.get(interval).cancel(true);
}
// 启动新的定时任务
ScheduledFuture<?> futureTask = taskScheduler.scheduleAtFixedRate(() -> {
for (Runnable task : tasks) {
task.run();
}
}, interval * 1000L);
scheduledTasks.put(interval, futureTask);
}
}
// 停止所有定时任务
public void stopAllTasks() {
for (ScheduledFuture<?> futureTask : scheduledTasks.values()) {
if (futureTask != null) {
futureTask.cancel(true);
}
}
scheduledTasks.clear();
}
}
2. TaskRunner.java
- 启动类,模拟任务添加和调度
package com.example.scheduler;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class TaskRunner implements CommandLineRunner {
private final DynamicTaskScheduler dynamicTaskScheduler;
public TaskRunner(DynamicTaskScheduler dynamicTaskScheduler) {
this.dynamicTaskScheduler = dynamicTaskScheduler;
}
@Override
public void run(String... args) throws Exception {
// 添加不同时间间隔的任务
dynamicTaskScheduler.addTask(5, () -> System.out.println("任务1 执行:" + System.currentTimeMillis()));
dynamicTaskScheduler.addTask(10, () -> System.out.println("任务2 执行:" + System.currentTimeMillis()));
// 启动所有任务
dynamicTaskScheduler.startAllTasks();
// 等待一段时间后停止任务
Thread.sleep(30000); // 等待30秒
dynamicTaskScheduler.stopAllTasks();
}
}
3. DemoApplication.java
- Spring Boot 启动类
package com.example.scheduler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
解释
-
DynamicTaskScheduler
类:- 使用
Map<Long, List<Runnable>>
来维护每个时间间隔对应的任务列表。 addTask(long intervalInSeconds, Runnable task)
方法用于将任务添加到指定的时间间隔中。startAllTasks()
方法启动所有时间间隔内的任务,并确保每个时间间隔的任务都被调度。stopAllTasks()
方法取消所有当前运行的定时任务。
- 使用
-
TaskRunner
类:- 在应用启动时,模拟添加任务并设置它们的执行时间。
- 启动所有任务并等待一段时间后停止它们。
这样,你可以通过维护一个 Map
来动态添加、更新和启动定时任务。每个时间间隔对应一组任务,所有这些任务会在相应的时间间隔内执行。
如果更好的方式可以在评论区留言讨论~~~