2012-12-17 86 views
0

我使用的是ExecutorService用於如下連接任務:shutdownNow時與執行服務

ExecutorService executor = Executors.newSingleThreadExecutor(); 
    Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions)); 
    connection = future.get(300000, TimeUnit.SECONDS); 
    executor.shutdownNow(); 

()的調用方法調用.connect()方法(專有API)。這種連接方法會產生各種線程池等。我擔心的是,如果將來超時並殺死執行程序,將來可能通過調用.connect()方法產生的線程也會結束嗎?我知道殺死一個線程也會殺死任何子線程,但這是否遵循相同的邏輯?

回答

2

你是對的,如果Future超時,一些懸掛的線程將保留。更糟糕的是,shutdownNow()甚至不會關閉您的池線程(更不用說私有API線程)。它只是停止接受新的工作。 ExecutorService一旦所有正在運行的任務完成,線程池將終止所有線程。

你可以做的是嘗試取消未來並中斷它。第一把手InterruptedException你的未來內:

class ConnectThread implements Callbale<ApplicationConnection> { 

    public ApplicationConnection call() { 
     try { 
      return prioprietaryApi.connect(); 
     } catch(InterruptedException e) { 
      prioprietaryApi.cleanUp(); 
      throw e; 
     } 
    } 

} 

現在只需運行:

future.cancel(true); 

但是您的專有API可能無法處理InterruptedException(它不會從connect()重新拋出它,而且你可能無法訪問任何cleanUp()方法

在這些情況下只是......忘了它,那Future最終會終止並自行清理,忽略事實在你不再等待它。當然這可能會導致各種可伸縮性問題。

順便說一句,如果你想實現的唯一的事情是限制方法運行的最大時間,考慮TimeLimiter

+0

如果我正確地理解了你,我現在正在做的事情會留下懸掛的線索,但最終未來將終止並清理自己?包含future.cancel(true)只有在connect()方法可以處理InterruptedException時纔有用? – Greg

+0

@Greg:你不再等待「未來」並不意味着它不再運行。當它結束時,它將像往常一樣清理,但是沒有人真的在等待結果。 –

1

javadoc

嘗試停止所有正在執行的任務,暫停 等待任務的處理,並返回那個正在等待 執行的任務列表。除了竭盡全力嘗試阻止處理主動執行任務之外,沒有任何保證。例如,典型的 實現將通過Thread.interrupt()取消,因此任何 未能響應中斷的任務都可能永遠不會終止。

+0

所以在說,你是說任何產生的線程也應該結束時關閉服務與shutdownNow?如果我要使用關機,那麼在Executor服務關閉之前,一切都會完成(包括產生)? – Greg

+0

不,shutdownNow()不保證,shutdown()保證了這種行爲。 – kosa