0

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

现在进行处理的对象/程序已经是一个单例了。所以现在我已经注意到只有 1 个实例在处理检查和处理。

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

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

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

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

4

1 回答 1

1

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

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

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

于 2011-09-13T04:43:52.290 回答