【问题标题】:Pause and resume scheduled task暂停和恢复计划任务
【发布时间】:2017-02-15 05:37:33
【问题描述】:

我需要暂停和恢复计划任务。

我看到了许多取消()任务的代码示例,但我还需要恢复/重新启动它。我看到了这样做的建议:

public void init(){
    scheduledTaskExecutor.getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
}
public void schedule(String id, Runnable task){
    ScheduledFuture<?> scheduledFuture = scheduledTaskExecutor.scheduleAtFixedRate(task);
    runningTaskRegistry.put(id, task);
}

public void suspend(String id){
    ScheduledFuture<?> scheduledFuture = runningTaskRegistry.get(serviceName);
    if(scheduledFuture != null){
        scheduledFuture.cancel(false);
        try{
            scheduledFuture.get();
        } catch (InterruptedException | ExecutionException | CancellationException e){
            // I do not want the currently running task finishing after this point
        }
    }
}

...然后我需要重新安排而不是重新开始。

这真的是最好的方法吗?

【问题讨论】:

  • 一般来说,是的,重新安排你的任务是最好的方法。想到的一个技巧是使用single-thread executor,并传递给它一个等待暂停条件为假的任务。
  • 单线程执行器在这里不是一个选项:我有几十个长时间运行的进程要运行,其中一些运行时间很长。
  • 老问题,但是如果在使用任务计划程序 GUI 时禁用选项(与结束选项不同)可用,那么为什么 schtasks 不支持它?您甚至可以使用 schtasks /query 看到禁用的任务显示为禁用。对我来说,这似乎是雷德蒙德的能力不足。

标签: java concurrency scheduled-tasks scheduling


【解决方案1】:

我更喜欢重新安排而不是暂停和恢复。不仅因为我不知道如何做,还因为暂停的任务可能不会释放它们的线程。在此期间,即使任务队列中还有其他任务在等待,这些执行线程也会阻塞并且不执行任何操作。

为了不丢失中间结果,您可以将它们放在另一个队列中,在安排新任务之前将它们拾取。您还可以根据该队列实现暂停和恢复。

【讨论】:

  • 我完全同意阻塞执行器线程不是一个好的解决方案。我只是认为执行程序本身可以将其删除到临时列表中,然后重新安排...... :-) 另一种解决方案可能是围绕 Runnable 创建一个 Wrapper/Proxy 并在那里处理暂停和恢复:不是通过阻塞线程而是通过在暂停时忽略原始可运行文件 :-) 这只会导致最小的开销和最少的样板代码。
  • @BTakacs 我认为这实际上取决于您的任务将要做什么以及您是否能够重用中间结果。如前所述,我知道没有实现允许高效可暂停和可恢复的任务,即线程不只是被阻塞。我建议您尝试BlockingQueue 来“停放”任务并再次拿起它们。如果你想让我给你举个例子,请告诉我。
猜你喜欢
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 2021-12-17
  • 2016-08-26
  • 2012-12-31
  • 1970-01-01
  • 2013-11-05
相关资源
最近更新 更多