java - 任务调度是如何实现的?

标签 java design-patterns scheduled-tasks scheduling

我已经做了很多工作来从网络服务中检索一些数据,但现在遇到了调度请求的问题,我不确定从哪里开始。

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

我正在考虑在收到事件或错误响应时在队列上创建一个查找请求,但这似乎并不理想 - 我会不断地使用消息,检查时间以查看请求是否应该尚未完成,如果没有,则将其放回队列中。

如果有人对如何解决此类问题提出建议,我将不胜感激。

最佳答案

首先,确保您按照事件需要执行的顺序将事件保存在队列中。这将确保您只需要查看队列的头部即可了解何时安排下一个事件。您可以为此使用 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();
        }
      }
    }
  }
}

关于java - 任务调度是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4256074/

相关文章:

scheduled-tasks - Sitecore清理代理和数据库清理

java - 如何使用java流从网络获取PDF文件

java - 为什么我们在jsp中写out.println()而不是System.out.println()?

java - 谷歌应用引擎: tasks vs threads?

language-agnostic - 任何人都可以用很好的例子向我解释可插拔适配器的概念吗?

design-patterns - 软件架构、并行处理和异步模式

python - 通过执行 pscp 的 Windows 任务计划程序运行 python 脚本时出现问题

Scala 中的 Java 风格 LinkedList

Java循环表达式打印列表

java - 我想比较两个相似的对象结构并列出差异