Spring Task Scheduler 连续任务
Spring Task Scheduler consecutive tasks
我不熟悉使用 Spring 任务计划程序来执行任务,所以这可能是一个基本问题。我有一个要在实现 Runnable
的 class 中处理的项目列表。这是我的任务 class:
public class ProcessTask<T> implements Runnable {
private String item;
public ProcessTask(String item) {
System.out.println("Starting process for " + item);
this.item = item;
}
@Override
public void run() {
System.out.println("Finishing task for " + item);
}
我想处理一个项目列表,每个项目在前一个任务开始后 10 秒开始。我知道我可以将每个设置为 运行 在前一个安排后 10 秒,但是我不想依赖它,因为其他进程可能会导致任务在 10 秒之前 运行正在过去。
所以在我的主要 class 中,我有以下内容:
Date end = new Date(cal.getTimeInMillis() + 10000); // this is the time that the task should be fired off, the first one being 10 seconds after the current time
for(String item : items) {
Calendar cal = Calendar.getInstance();
cal.setTime(end);
System.out.println("Next task fires at " + cal.getTime());
ProcessTask task = new ProcessTask(item);
ScheduledFuture<?> future = taskScheduler.schedule(task, end);
end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
}
第一个任务在代码 运行s 后 10 秒触发,这很棒。但是其余的项目会立即安排,而不是等待 10 秒。我确实理解为什么会发生这种情况 - 因为 taskScheduler.schedule
是异步的,所以 for 循环会继续,其余项目会在 10 秒后安排。
我尝试让主线程休眠一秒钟,然后检查 ScheduledFuture
是否已完成,然后再安排下一个任务,例如:
while(!future.isDone()) {
Thread.sleep(1000);
System.out.println("is future done: " + future.isDone());
}
如果我在上面的块中 ScheduledFuture<?> future = taskScheduler.schedule(task, end);
之后立即添加此块,则 future.isDone()
始终 returns false,并且 ProcessTask
run()
方法永远不会被调用。
请问有什么方法可以通过ScheduledFuture
判断上一个任务是否结束,如果没有继续等待?总体上有更好的方法来做到这一点吗?提前致谢。
所以你不知道任务什么时候结束,但是10秒后,你想要下一个任务运行。因此,只有在完成该任务后才能进行计划。
所以,有一个基础抽象class,它负责管道。
public abstract class ScheduleTaskAfterRun<T> implements Runnable {
protected void executeContent();
private Runnable nextTask;
private taskScheduler; // init somehow, probably by constructor...
public void setNextTask(Runnable r) {
nextTask = r;
}
@Override
public void run() {
executeContent();
scheduleNextTask();
}
private void scheduleNextTask() {
if(nextTask == null) {
System.out.println("No task to handle, finished!");
return;
}
Date end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
ScheduledFuture<?> future = taskScheduler.schedule(nextTask, end);
}
}
我不熟悉使用 Spring 任务计划程序来执行任务,所以这可能是一个基本问题。我有一个要在实现 Runnable
的 class 中处理的项目列表。这是我的任务 class:
public class ProcessTask<T> implements Runnable {
private String item;
public ProcessTask(String item) {
System.out.println("Starting process for " + item);
this.item = item;
}
@Override
public void run() {
System.out.println("Finishing task for " + item);
}
我想处理一个项目列表,每个项目在前一个任务开始后 10 秒开始。我知道我可以将每个设置为 运行 在前一个安排后 10 秒,但是我不想依赖它,因为其他进程可能会导致任务在 10 秒之前 运行正在过去。
所以在我的主要 class 中,我有以下内容:
Date end = new Date(cal.getTimeInMillis() + 10000); // this is the time that the task should be fired off, the first one being 10 seconds after the current time
for(String item : items) {
Calendar cal = Calendar.getInstance();
cal.setTime(end);
System.out.println("Next task fires at " + cal.getTime());
ProcessTask task = new ProcessTask(item);
ScheduledFuture<?> future = taskScheduler.schedule(task, end);
end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
}
第一个任务在代码 运行s 后 10 秒触发,这很棒。但是其余的项目会立即安排,而不是等待 10 秒。我确实理解为什么会发生这种情况 - 因为 taskScheduler.schedule
是异步的,所以 for 循环会继续,其余项目会在 10 秒后安排。
我尝试让主线程休眠一秒钟,然后检查 ScheduledFuture
是否已完成,然后再安排下一个任务,例如:
while(!future.isDone()) {
Thread.sleep(1000);
System.out.println("is future done: " + future.isDone());
}
如果我在上面的块中 ScheduledFuture<?> future = taskScheduler.schedule(task, end);
之后立即添加此块,则 future.isDone()
始终 returns false,并且 ProcessTask
run()
方法永远不会被调用。
请问有什么方法可以通过ScheduledFuture
判断上一个任务是否结束,如果没有继续等待?总体上有更好的方法来做到这一点吗?提前致谢。
所以你不知道任务什么时候结束,但是10秒后,你想要下一个任务运行。因此,只有在完成该任务后才能进行计划。 所以,有一个基础抽象class,它负责管道。
public abstract class ScheduleTaskAfterRun<T> implements Runnable {
protected void executeContent();
private Runnable nextTask;
private taskScheduler; // init somehow, probably by constructor...
public void setNextTask(Runnable r) {
nextTask = r;
}
@Override
public void run() {
executeContent();
scheduleNextTask();
}
private void scheduleNextTask() {
if(nextTask == null) {
System.out.println("No task to handle, finished!");
return;
}
Date end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
ScheduledFuture<?> future = taskScheduler.schedule(nextTask, end);
}
}