我在Apache Tomcat上使用JSP/Servlet。我必須每10分鐘運行一次方法。我怎樣才能做到這一點?如何以固定的時間間隔運行後臺作業方法?
上 ScheduledExecutorService回答
讀它必須由一個ServletContextListener
public class MyContext implements ServletContextListener
{
private ScheduledExecutorService sched;
@Override
public void contextInitialized(ServletContextEvent event)
{
sched = Executors.newSingleThreadScheduledExecutor();
sched.scheduleAtFixedRate(new MyTask(), 0, 10, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent event)
{
sched.shutdownNow();
}
}
也可啓動,您可以嘗試使用Java Timer從ServletContextListener,但它不是在一個Java EE容器推薦,因爲它帶走的控制線程資源從容器。 (ScheduledExecutorService的第一個選項是要走的路)。
Timer timer = new Timer("MyTimer");
MyTask t = new MyTask();
//Second Parameter is the specified the Starting Time for your timer in
//MilliSeconds or Date
//Third Parameter is the specified the Period between consecutive
//calling for the method.
timer.schedule(t, 0, 1000*60*10);
而且MyTask
實現TimerTask
是一個類,所以你必須與你的代碼重寫run方法實現了Runnable
接口:
class MyTask extends TimerTask
{
public void run()
{
// your code here
}
}
當你在Tomcat中,這僅僅是一個準系統servlet容器,你不能使用EJB的@Schedule
來達到Java EE規範推薦的目的。您最好的選擇是來自Java 1.5的java.util.concurrent
包的ScheduledExecutorService
。你可以用一個ServletContextListener
喜歡幫助觸發此如下:
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeTask(), 0, 10, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
其中SomeTask
類是這樣的:
public class SomeTask implements Runnable {
@Override
public void run() {
// Do your job here.
}
}
如果你實際上使用與EJB支持和所有真正的Java EE容器em(像Glassfish,JBoss AS,TomEE等),那麼你可以使用@Singleton
EJB和@Schedule
方法。這樣容器就會擔心自己會集中並銷燬線程。所有你需要的是那麼下面的EJB:
@Singleton
public class SomeTask {
@Schedule(hour="*", minute="*/10", second="0", persistent=false)
public void run() {
// Do your job here.
}
}
注意,這樣你就可以繼續使用透明容器管理事務的常用方式(@PersistenceContext
等),這是不可能的ScheduledExecutorService
—你必須手動獲取實體管理器並手動啓動/提交/結束事務,但是在默認情況下,您已經在像Tomcat這樣的準系統servlet容器上沒有其他選項。
請注意,您絕不應在運行Java EE Web應用程序的所謂「終生長」中使用Timer
。它有這使得它不適合於Java EE中使用以下主要問題(從Java Concurrency in Practice引用):
Timer
是系統時鐘的變化很敏感,ScheduledExecutorService
不是。Timer
只有一個執行線程,所以長時間運行的任務可以延遲其他任務。ScheduledExecutorService
可以配置任意數量的線程。- 在
TimerTask
中拋出的任何運行時異常都會終止一個線程,從而導致Timer
死機,即計劃任務將不再運行(直到您重新啓動服務器)。ScheduledThreadExecutor
不僅捕獲運行時異常,但它可以讓你處理它們,如果你想。拋出異常的任務將被取消,但其他任務將繼續運行。
很好的答案,謝謝@BususC。有一個問題:如果我需要更改調用之間的間隔,我將如何修改調度程序? 例如我有一些'頻率',可以由用戶在webgui中設置,代表以秒爲單位的時間間隔。 – Gewure
- 1. 如何安排以多個時間間隔運行的作業
- 2. 如何在固定時間間隔內運行magento中的cron.php
- 3. 在指定的時間間隔內運行彈簧作業
- 4. Jmeter-Thread-如何以固定的時間間隔運行一組用戶
- 5. 以固定間隔
- 6. 當應用程序未運行時,以固定的時間間隔在後臺重複調用一個函數
- 7. 如何在固定的時間間隔重新啓動在後臺
- 8. Quartz.net作業完成後的時間間隔重複作業
- 9. 如何在固定的時間間隔後重新列表listview?
- 10. Android:如何在固定的時間間隔後刷新背景?
- 11. 如何在固定的時間間隔後滑動文本
- 12. 運行cron作業一些固定的時間
- 13. 如何以固定的時間間隔調用函數?
- 14. 在指定的時間間隔內運行強制方法
- 15. 在後臺運行的時間間隔計算
- 16. 設置cron作業的特定時間,然後設置間隔
- 17. C++ 11計時庫 - 如何在特定的時間間隔後執行方法?
- 18. 以固定的時間間隔重複執行任務
- 19. 如何在特定時間之間運行Quarz Cron作業?
- 20. Java:以指定的時間間隔執行方法
- 21. Cron作業超出時間間隔運行
- 22. 如何確保定時記錄在固定的時間間隔?
- 23. 長時間運行ETL過程 - 後臺作業,Spark,Hadoop
- 24. Android背景循環不會以固定的時間間隔運行
- 25. 無法使horizontalSlider以固定時間間隔滑動
- 26. CRON:在特定時間運行作業
- 27. windows服務在C++中以一定的時間間隔運行一個方法
- 28. 在固定的時間間隔
- 29. 如何正確使用AlarmManager類以固定的時間間隔執行任務?
- 30. for循環在作業schedueler resque在設定的時間間隔運行
好吧我得到了它,但從那裏我必須調用此方法。我必須在應用程序啓動後立即啓動 –
[永遠不要在Java EE中使用Timer](http://stackoverflow.com/questions/9173132/stop-scheduled-timer-when-shutdown-tomcat/9186070#9186070 )。 – BalusC
謝謝@BalusC我在我的回答中明確提到過。 – user1697575