如何实施任务调度?

时间:2010-11-23 12:34:46

标签: java design-patterns scheduled-tasks scheduling

我已经做了一大堆工作来从Web服务中检索一些数据,但是现在遇到了向它安排请求的问题,我不确定从哪里开始。

我在jms队列中收听事件,收到事件后我需要在一段时间后向Web服务发出请求。持续时间因事件属性而异。如果Web服务返回false,我需要继续计划请求,直到它返回true。

我在考虑在收到事件或错误响应时在队列上创建查找请求,但这似乎并不理想 - 我会不断消耗消息,检查时间以查看请求是否应该如果没有,那就把它放回队列。

如果有人就如何实施这样的问题得到建议我真的很感激。

4 个答案:

答案 0 :(得分:6)

首先,确保按照需要执行的顺序将事件保留在队列中。这将确保您只需查看队列的头部以查看何时应安排下一个事件。您可以使用PriorityQueue

您处理事件的线程将轮询此队列中的项目并处理它们。看看头部项目,看看下一个事件何时需要运行。选择一个对象作为锁定对象,并在该对象上调用主线程Object.wait(long),将该方法传递给毫秒,直到需要运行下一个事件。

如果有新线程进入,请将其添加到适当位置的队列中。如果项目位于队列的头部,这意味着线程需要更快地唤醒。在锁定对象上调用Object.notifyAll()以唤醒处理线程。它会看到没有任何东西可以处理并在适当的时间内重新入睡。

public class ProcessingQueue extends Thread {

  private PriorityQueue<Task> tasks;  

  private volatile boolean isRunning = true;

  public void addTask(Task t) {
    synchronized (this.tasks) {
      this.tasks.offer(t);
      // this call requires synchronization to this.tasks
      this.tasks.notifyAll();
    }
  }

  public void shutdown() {
    this.isRunning = false;
    synchronized (this.tasks) {
      this.notifyAll();
    }
  }

  public void run() {
    while (this.isRunning) {
      synchronized (this.tasks) {
        Task t = this.tasks.peek();
        // by default, if there are no tasks, this will wake every 60 seconds
        long millisToSleep = 60000;
        // getExecuteMillis() should return the time, in milliseconds, for execution
        if (t != null) millisToSleep = t.getExecuteMillis() - System.currentTimeMillis();
        if (millisToSleep > 0) {
          try {
            // this line requires synchronization to this.tasks
            // and the lock is removed while it waits
            this.tasks.wait(millisToSleep);
          } catch (InterruptedException e) {
          }
        }
        t = this.tasks.poll();
        if (t != null) {
          t.execute();
        }
      }
    }
  }
}

答案 1 :(得分:4)

我同意使用三维派对库。我使用石英框架。 http://www.quartz-scheduler.org/

答案 2 :(得分:2)

使用现有的OSS调度程序:http://java-source.net/open-source/job-scheduler

你总是可以自己动手,但我不推荐它。

调度程序的一个重要特性应该是它能够在重启/崩溃后继续存在。

答案 3 :(得分:0)

我决定使用版本3中引入的Spring Task Scheduling。它提供基于时间和间隔两个时刻的池化,调度,如果需要更多自定义,它有一个cron选项。我没有深入研究Quartz可以实现的深度,但它也提供了与之集成的功能。