安排任务,确保任务正在执行
我有一个应用程序可以检查互联网上的资源是否有新邮件。如果有新邮件,它会对它们进行一些处理。这意味着根据邮件数量,处理可能只需要几秒钟到几小时。
现在执行处理的对象/程序已经是单例了。所以现在我已经注意到实际上只有 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 分钟左右的休息时间。
I have an application that checks a resource on the internet for new mails. If there is are new mails it does some processing on them. This means that depending on the amount of mails it might take just a few seconds to hours of processing.
Now the object/program that does the processing is already a singleton. So right now I already took care of there really only being 1 instance that's handling the checking and processing.
However I only have it running once now and I'd like to have it continuously running, checking for new mails more or less every 10 minutes or so to handle them in a timely manner.
I understand I can take care of this with Timer/Timertask or even better I found a resource here: http://www.ibm.com/developerworks/java/library/j-schedule/index.html that uses Scheduler/SchedulerTask. But what I am afraid of.. is if I set it to run every 10 minutes and a previous session is already processing data it will put the new task in a stack waiting to be executed once the previous one is done. So what I'm afraid of is for instance the first run running for 5 hours and then, because it was busy all the time, after that it will launch 5*6-1=29 runs immediately after each other checking for mails and/do some processing without giving the server a break.
Does anyone know how I can solve this?
P.S. the way I have my application set up right now is I'm using a Java Servlet on my tomcat server that's launched upon server start where it creates a Singleton instance of my main program, then calls some method to do the fetching/processing. And what I want is to repeat that fetching/processing every "x" amount of time (10 minutes or so), making sure that really only 1 instance is doing this and that really after each run 10 minutes or so are given to rest.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,Timer + TimerTask 可以非常干净地处理这个问题。如果您使用 Timer.scheduleAtFixedRate() 您会注意到文档说它将尝试“补”迟到事件,维持长期执行力。但是,可以通过使用 TimerTask.scheduledExecutionTime()。其中的示例可让您确定任务是否太迟而无法运行,并且您可以直接返回而不用执行任何操作。实际上,这将“清除 TimerTask 的队列”。
值得注意的是:TimerTask 使用单个线程来执行,因此它不会并排生成任务的两个副本。
附注部分,您不必在一次运行中处理队列中的所有 10k 电子邮件。我建议使用 TimerTask.scheduledExecutionTime() 处理固定的时间来计算出您还有多长时间,然后返回。这使您的流程更加灵活,清理运行之间的堆栈,并且如果您正在进行聚合,则确保您不必重建太多数据,例如,如果服务器在任务中间重新启动。但这个建议是基于一般性,因为我不知道你在任务中做什么:)
Actually, Timer + TimerTask can deal with this pretty cleanly. If you schedule something with Timer.scheduleAtFixedRate() You will notice that the docs say that it will attempt to "make up" late events to maintain the long-term period of execution. However, this can be overcome by using TimerTask.scheduledExecutionTime(). The example therein lets you figure out if the task is too tardy to run, and you can just return instead of doing anything. This will, in effect, "clear the queue" of TimerTask.
Of note: TimerTask uses a single thread to execute, so it won't spawn two copies of your task side-by-side.
On the side note part, you don't have to process all 10k emails in the queue in a single run. I would suggest processing for a fixed amount of time using TimerTask.scheduledExecutionTime() to figure out how long you have, then returning. That keeps your process more limber, cleans up the stack between runs, and if you are doing aggregates, ensures that you don't have to rebuild too much data if, for example, the server is restarted in the middle of the task. But this recommendation is based on generalities, since I don't know what you're doing in the task :)