首先,确保按照需要执行的顺序将事件保留在队列中.这将确保您只需查看队列的头部以查看何时应安排下一个事件.您可以使用PriorityQueue.
处理事件的线程将轮询该队列中的项目并处理它们.看看头部项目,看看下一个事件何时需要运行.选择一个对象用作锁定对象,让主线程在该对象上调用Object.wait(long),将该方法传递给毫秒,直到需要运行下一个事件.
如果有新线程进入,请将其添加到适当位置的队列中.如果项目位于队列的头部,这意味着线程需要更快地唤醒.在锁定对象上调用Object.notifyAll()以唤醒处理线程.它将看到没有任何东西可以处理并在适当的时间内重新入睡.
public class ProcessingQueue extends Thread {
private PriorityQueue 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();
}
}
}
}
}