【问题标题】:How to use TaskExecutorService discarding overlapping task in java如何使用TaskExecutorService在java中丢弃重叠任务
【发布时间】:2012-11-17 12:52:03
【问题描述】:

我有一个运行 2 个独立的独立 java 轮询工具的场景,它会以 5 分钟的固定间隔运行一些特定的任务。

我的场景是(对于每个轮询服务):

1) 如果一个任务 T0 需要超过 5 分钟才能运行,同时在 5 分钟后 T5 来尝试执行,我会丢弃它,而不是等待,或者重新启动(丢弃重叠任务)

2) 下一个任务会在 T10 正常开始。

我的问题是使用 Quartz 会不会是大材小用?如果我使用 TaskExecutorService,我如何在时间 X 上检查一旦在时间 X-5 开始的任务已经在运行,我应该丢弃它。

注意: 1)我必须使用JDK

2) 我没有在 spring 之类的任何框架下使用。

3) 它是一个桌面工具,所以我需要启动它,它会运行..

任何代码 sn-p 或方向表示赞赏。

已更新以下评论的答案:

是的,它在单个工具中运行的任务之间。工具不同,工具之间没有联系,它们会单独运行,没有关系。

单个工具以 5 分钟的间隔运行相同的任务(就像每个文件分钟一样,它会在目录中查找文件,如果找到,则解析这些文件并使用它们)。

如果,例如,如果任务当前正在运行,从第一分钟开始(可能需要任何时间),5 分钟后该工具再次启动该任务以寻找新文件,但这次它不会解析/使用它,因为先前的任务已经在运行处理一些文件。所以新任务将不会执行并且系统将转储它(没有队列/没有等待/没有顺序作业)。

另一个新任务将以 5 倍的时间再次运行,如果没有其他任务在运行,它将解析和处理这些文件。

【问题讨论】:

  • 当你说放弃一个任务时,它是在单个工具中运行的任务之间吗?为什么需要丢弃它?你有不同的任务吗?如果您在 5 分钟的间隔内运行相同的任务,那么保证一个任务在第一个任务完成后 5 分钟运行对您有好处吗?

标签: java multithreading scheduled-tasks


【解决方案1】:

看到评论中问题的回复后,可以使用Excecutors获取ScheduledExecutorService。然后,您可以使用方法scheduleWithFixedDelay 提交您的任务。此方法在运行之间有延迟重新运行任务。对您而言,好处是延迟计数在当前运行完成后开始。这将在不使用布尔变量或 ReentrantLock 的情况下为您提供所需的内容,因为您不会同时运行两个任务。您只需要小心捕获异常,因为异常会导致任务的后续运行被取消。

假设你有一个实现可运行的类 MyTask

public class MyTask implements Runnable{

  public void run() {
     try {
           //your task code here
     } catch (...) {
        //deal with the exceptions here               
     }
  }

}

假设您将从 main 方法运行,您现在可以使用该类来安排重复执行的任务:

public class TaskRunner{

private static final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1);

  public static void main(String[] args) {
    taskScheduler.scheduleWithFixedDelay(new MyTask(),0,5,TimeUnit.MINUTES);  
  }

}

【讨论】:

  • 非常感谢,这段代码没有任务重叠,一次只运行一个任务,新的任务在 5 分钟后开始。但现在我遇到的问题是,下一个 5 分钟在前一个结束后开始。不是原来的 5 分钟间隔。比如,如果第一个从上午 10:00 开始并在 10:07 结束,那么下一个从 10:12 开始而不是在 10:10 开始,因为在 10:05 系统应该什么都不做并继续。那可能吗 ?否则我会坚持目前的解决方案。
  • 上面的代码与您提到的行为相同。如果一个从 10 点开始并在 10:07 结束,则下一个从 10:12 开始。如果从 10:12 开始运行 3 分钟并在 10:15 结束,则下一个从 10:20 开始。等等。您可以进行测试并打印每个任务开始和结束的时间,以查看发生了什么以确保这一点。
  • 另外注意:中间没有新任务提交。重新安排的任务是相同的。所以在你给出的场景中,没有从 10:10 开始的任务。任务开始并完成,然后重新安排在 5 分钟后再次运行。
【解决方案2】:

解决方案很简单:使用 ScheduledThreadPoolExecutor.scheduleAtFixedRate(task, 5, min)。声明一个公共布尔变量isRunning=false。每个任务在开始时都会检查这个变量,如果已经设置,则退出,否则将其设置为 true 并运行。最后,将其设置为 false。检查和设置应在同步块中完成。

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 2013-06-05
    • 2020-03-21
    • 1970-01-01
    • 2020-02-04
    • 2014-11-18
    • 2013-09-15
    • 1970-01-01
    相关资源
    最近更新 更多