我需要每隔几个小时执行一项任务,我正在寻找最有效的解决方案。我想到了两种方法:
1)忙着等待
while(true){
doMyJob()
wait(2*hour);
}
2)执行者安排:
executor.schedule(new MyJobTask(),2,TimeUnit.HOUR);
...
class MyJobTask implements Runnable{
void run(){
doMyJob();
...
executor.schedule(new MyJobTask(),2,TimeUnit.HOUR);
}
您能告诉我哪种解决方案更有效率,以及在哪种情况下更优选(如果有的话)。直觉上,我会寻求第二种解决方案,但我找不到任何证明我直觉的东西。如果您有其他解决方案 - 请分享。解决方案也应该具有内存效率(这就是我遇到困境的原因 - 我是否需要创建并保留一个ThreadPool对象,每两个小时只执行一次简单的工作)。
答案 0 :(得分:3)
建议的解决方案中没有一个在EE容器中是真的可取的(你应该避免弄乱线程),你似乎根据问题的标记来定位。
从Java EE 5开始,有timer service根据我的测试可以很好地处理更长的超时时间,比如你的例子中的2小时。有一点,你真的不应该忘记 - 引用上述教程:
定时器是持久的。如果服务器关闭(甚至崩溃),则会保存计时器,并在重新启动服务器时再次激活计时器。如果计时器在服务器关闭时到期,则容器将在服务器重新启动时调用@Timeout方法。
如果由于某种原因无法接受此解决方案,您应该查看Quartz Scheduler。到目前为止,它的可能性超出了您的要求,但至少它为您提供了一个随时可用的解决方案,它可以保证与各种应用服务器的兼容性。
答案 1 :(得分:1)
两者应具有相同的效率,但我建议使用ScheduledExecutorService
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(new MyJobTask(), 0, 2, TimeUnit.HOUR);
有几个原因,详见:A better way to run code for a period of time
但重要的是,ScheduledExecutorService
允许您使用多个线程,以便花费很长时间的任务不一定需要备份您的任务队列(该服务可以同时运行2个任务) 。此外,如果doMyJob
引发异常,ScheduledExecutorService
将继续安排您的任务而不是被取消,因为它无法重新安排任务。