我同意使用三维派对库。我使用石英框架。 http://www.quartz-scheduler.org/
首先,确保按照需要执行的顺序将事件保留在队列中。这将确保您只需查看队列的头部以查看何时应安排下一个事件。你可以使用 PriorityQueue 为了这。
PriorityQueue
处理事件的线程将轮询该队列中的项目并处理它们。看看头部项目,看看下一个事件何时需要运行。选择一个对象用作锁定对象并进行主线程调用 Object.wait(long) 在该对象上,传递方法的毫秒数,直到需要运行下一个事件。
Object.wait(long)
如果有新线程进入,请将其添加到适当位置的队列中。如果项目位于队列的头部,这意味着线程需要更快地唤醒。呼叫 Object.notifyAll() 在锁定对象上唤醒处理线程。它将看到没有任何东西可以处理并在适当的时间内重新入睡。
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(); } } } } }
使用现有的OSS调度程序: http://java-source.net/open-source/job-scheduler
你总是可以自己动手,但我不推荐它。
调度程序的一个重要特性应该是它能够在重启/崩溃后幸存下来。
我决定一起去 Spring任务调度 它已在版本3中引入。它提供基于时间和间隔两个时刻的池化,调度,如果需要更多自定义,则它具有cron选项。我没有深入研究Quartz可以实现的深度,但它也提供了与之集成的深度。