调度任务,确保任务正在执行

时间:2011-09-13 04:30:00

标签: java tomcat singleton schedule

我有一个应用程序可以检查互联网上的资源是否有新邮件。如果有新邮件,它会对它们进行一些处理。这意味着根据邮件数量,可能只需几秒到几小时的处理时间。

现在进行处理的对象/程序已经是单例。所以现在我已经完成了处理检查和处理的实例。

但是我现在只运行一次,我希望它能够持续运行,每10分钟或多或少检查一次新邮件,以便及时处理。

我知道我可以用Timer / Timertask来处理这个问题,或者更好的是我在这里找到了一个资源:http://www.ibm.com/developerworks/java/library/j-schedule/index.html使用Scheduler / SchedulerTask。但我害怕的是......如果我将它设置为每10分钟运行一次并且前一个会话已经在处理数据,那么它将把新任务放在堆栈中,等待上一个完成后再执行。所以我害怕的是例如第一次运行5小时然后,因为它一直很忙,之后它将在彼此检查邮件和/后立即启动5 * 6-1 = 29次运行在不给服务器休息的情况下进行一些处理。

有谁知道如何解决这个问题?

P.S。我现在设置应用程序的方式是我在我的tomcat服务器上使用Java Servlet,它在服务器启动时启动,它创建我的主程序的Singleton实例,然后调用一些方法来进行提取/处理。我想要的是重复每隔“x”时间(10分钟左右)取出/处理,确保实际上只有1个实例正在执行此操作,并且确实在每次运行10分钟左右后才会休息。

1 个答案:

答案 0 :(得分:1)

实际上,Timer + TimerTask可以很干净地处理这个问题。如果您使用Timer.scheduleAtFixedRate()安排某些事情,您会注意到文档会说它将尝试“弥补”延迟事件以维持长期执行期。但是,使用TimerTask.scheduledExecutionTime()可以克服这个问题。其中的示例可以让您弄清楚任务是否太迟而无法运行,您可以返回而不是做任何事情。实际上,这将“清除TimerTask的队列”。

值得注意的是:TimerTask使用单个线程来执行,因此它不会并排生成两个任务副本。

在旁注部分,您不必在一次运行中处理队列中的所有10k电子邮件。我建议使用TimerTask.scheduledExecutionTime()处理一段固定的时间,以确定你有多长时间然后返回。这可以使您的流程更加灵活,在运行之间清理堆栈,如果您正在进行聚合,则确保您不必重建太多数据,例如,如果服务器在任务中间重新启动。但是这个建议是基于一般性的,因为我不知道你在任务中做了什么:)