2012-03-29 779 views
10

我在我的應用程序中使用ScheduledExecutorService。我需要在某些Utility類中不時使用它來運行預定的線程。ScheduledExecutorService:何時應該調用shutdown?

在靜態字段中保存ScheduledExecutorService是一個好設計嗎?在這種情況下是否必須調用ScheduledExecutorService.shutdown()?如果我不調用關機會有什麼風險?

這就是我想這樣做:

private static ScheduledExecutorService exec = Executors.newScheduledThreadPool(5); 

public void scheduleTask(String name) { 
     Future<?> future = futuresMapping.get(name); 
     if(future!=null && !future.isDone()) 
      future.cancel(true); 

     //execute once 
     Future<?> f = scheduledExecutor.schedule(new MyTask()), 1, TimeUnit.MINUTES); 
     futuresMapping.put(name, f); 
} 

謝謝

回答

5

您應該始終調用shutdown()或shutdownNow()。如果你不這樣做,你的應用程序可能永遠不會終止,因爲仍然有線程處於活動狀態(取決於你如何終止你的應用程序,無論是否在託管環境中)。

通常情況下,您會從某種生命週期事件方法調用shutdown(),例如從Spring的DisposableBean.destroy()中調用,或者如果您沒有使用任何框架,請在退出應用程序之前調用它。

+0

我試着添加scheduledExecutor.shutdownNow();在我的ServletContextListener中,但是我在tomcat日誌中發現錯誤,說「Web應用程序[/ servlet]似乎已經啓動了一個名爲[Timer-0]的線程,但未能阻止它,這很可能導致內存泄漏。 」。我怎樣才能避免這個錯誤?感謝您的幫助 – lili 2012-03-29 17:20:32

+0

shutdownNow()是非阻塞呼叫,將立即返回。之後應該調用awaitTermination(),直到線程池實際關閉爲止。 – maximdim 2012-03-29 17:45:01

+0

我試過了,它沒有工作。我應該等30秒以上嗎?我在http://stackoverflow.com/questions/9930624/tomcat7-and-scheduledexecutorservice-shutdownnow上寫了更多的細節 謝謝 – lili 2012-03-29 17:47:56

3

有效的Java第二版說:

這裏是如何告訴執行正常終止(如果你未能做到這一點,它可能是你的VM不會退出):

executor.shutdown();