2012-02-01 85 views
1

我有一個Runnable實現,它可能需要一些時間,我試圖使用ScheduledThreadPoolExecutorscheduleAtFixedRate方法來安排它。現在我想確保關閉是優雅的,意味着,在終止之前,任務應該被允許完全運行。我已經寫下關閉代碼。等待任務完成,然後終止ScheduledThreadPoolExecutor

public void shutDown() throws Exception { 
    try { 
     LOG.info("Gracefully shutting down executor"); 
     executor.shutdown(); 
     if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) { 
      // cancels currently executing tasks. 
      LOG.info("Executor is still alive. Forcing executor thread pool to shut down"); 
      executor.shutdownNow(); 

      // Wait a while for tasks to respond to being cancelled 
      if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) { 
       LOG.fatal("Executor thread pool did not terminate"); 
       throw new Exception("Unable to shut down executor thread pool forcefully"); 
      } 
      LOG.info("Executor shut down."); 
     } 
    } catch (Exception e) { 
     LOG.error("Exception shutting down executor", e); 
     throw e; 
    } 
} 

但問題是這樣的,我必須指定時間來等待明確的,我無法預測的任務提前所用的時間。有沒有辦法讓執行者無限期地等待,直到執行任務完成而不必提及時間等待?還是有更好的方法來處理上述情況?

感謝

Jitendra

+0

shutdown()應該做適當的終止權嗎?根據文檔,shutdown()啓動有序關閉,在其中執行先前提交的任務,但不會接受任何新任務。任何你有其他代碼與awaitTermination(...)相關的原因;如果在一定的時間間隔內沒有完成,您是否要強制關閉? – kosa 2012-02-01 22:24:20

+0

我認爲,它只啓動關閉並退出,不會阻塞或等待線程關閉。 – RandomQuestion 2012-02-01 22:27:57

+0

我想要某種阻塞呼叫,以便我確切知道何時終止任務 – RandomQuestion 2012-02-01 22:32:49

回答

1

:因此,在短期是這樣的(只要我們處理完任務加載調度是安全的關閉它意味着我們不允許任何進一步的任務,從此被提交通知)最簡單的解決方案就是「過度配置」。我建議你使用一個巨大的超時時間,這決不會超過執行單個任務所需的時間,如:

// do you have tasks that can take more than 2^63 - 1 days to finish? :) 
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
0

使用shutdown()開始正常終止,然後用awaitTermination(long, TimeUnit)等待執行的服務來完成關停。

0

正如在註釋executor.shutdown()中指出的那樣,不會強制任何任務退出,而是會阻止新的任務被接受。看看javadoc

是,如果你想盡快,因爲他們完全得到你的任務不放,可以實現Callable<T>,而不是一個Runnable,它是一個通用型的,返回類型T的值的另一種建議。然後你可以用這個Callable<T>轉換成FutureTask<V>並將其提交給您的ScheduledThreadPoolExecutor。然後,您可以在他們完成工作後立即完成任務並可用。

ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(n); 
Callable<Integer> myTask = . . .; 
FutureTask<Integer> task = new FutureTask<Integer>(myTask); 
schedulerExecutor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); 
schedulerExecutor.shutdown();