2012-06-20 72 views
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對象,每兩個小時只做一件簡單的工作)。

+0

什麼EE規格你必須使用? 1.4,5或6? – fvu

+0

相關:http://stackoverflow.com/questions/5357033/background-timer-task-in-jsp-servlet-web-application/5357856#5357856絕對不會忙着等待。 – BalusC

+0

我喜歡EE 6 – Karusmeister

回答

3

在EE容器內部(您應該避免與線程混淆),建議的解決方案都不是真的可取,您似乎根據問題的標籤來定位目標。

從Java EE 5開始,有timer service,根據我的測試,它可以很好地處理較長的超時,比如您的示例中的2小時。有一點,你真的不應該忘記 - 引用從上述教程:

定時器是持久的。如果服務器關閉(甚至崩潰),則定時器將被保存並在服務器重新啓動時再次變爲活動狀態。如果計時器在服務器關閉時到期,那麼容器將在服務器重新啓動時調用@Timeout方法。

如果由於某種原因這種解決方案是不可接受的,你應該看看Quartz Scheduler。它的可能性遠遠超過了您的要求,但至少它爲您提供了一個即可使用的解決方案,該解決方案可以保證與各種應用程序服務器的兼容性。

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將繼續安排您的任務,而不是被取消,因爲它無法重新安排任務。

+0

這真的不像我在EJB中做的事情。你認爲這不會產生問題,所以你更喜歡EJB定時器服務? – esej