我已经做了很多工作来从网络服务中检索一些数据,但现在遇到了调度请求的问题,我不确定从哪里开始。
我监听事件的 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/