0

我需要每隔几个小时执行一次任务,我正在为此寻找最有效的解决方案。我想到了两种方法:

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 对象只是为了每两个小时做一个简单的工作)。

4

2 回答 2

3

在 EE 容器中(您应该避免弄乱线程),建议的解决方案都不是真正可取的,您似乎根据问题的标签来定位它。

从 Java EE 5 开始,有一个计时器服务,根据我的测试,它可以很好地使用更长的超时时间,例如您的示例中的 2 小时。不过,有一点你真的不应该忘记 - 引用上述教程:

计时器是持久的。如果服务器关闭(甚至崩溃),计时器将被保存,并在服务器重新启动时再次变为活动状态。如果在服务器关闭时计时器到期,则容器将在服务器重新启动时调用@Timeout 方法。

如果由于某种原因该解决方案不可接受,您应该查看Quartz Scheduler。它的可能性远远超出了您的要求,但至少它为您提供了一个即用型解决方案,它保证了与各种应用程序服务器的兼容性。

于 2012-06-20T16:43:02.267 回答
1

两者的效率应该差不多,但我建议使用ScheduledExecutorService

Executors.newSingleThreadScheduledExecutor()
    .scheduleAtFixedRate(new MyJobTask(), 0, 2, TimeUnit.HOUR);

有几个原因,这里详述:运行代码一段时间的更好方法

但重要的是,ScheduledExecutorService它允许您使用多个线程,这样耗时较长的任务就不必备份您的任务队列(该服务可以同时运行您的两个任务)。此外,如果doMyJob抛出异常,ScheduledExecutorService将继续安排您的任务,而不是因为未能重新安排任务而被取消。

于 2012-06-20T16:38:34.453 回答