2013-12-19 56 views
0

我想啓動一個線程,並取消它,如果它未在5秒內完成:如何中斷給定Future對象的線程?

private final class HelloWorker implements Callable<String> { 
    public String call() throws Exception { 
     while(true) { 
      if (Thread.isInterrupted()) { 
       return null; 
      } 
     } 
     return performExpensiveComputation(); 
    } 

    private String performExpensiveComputation() { 
     // some blocking expensive computation that may or may not take a very long time 
    } 
} 

private ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize); 
Future<String> future = executorService.submit(new HelloWorker()); 

try { 
    String s = future.get(5, TimeUnit.SECONDS); 
} catch (TimeoutException e) { 
    future.cancel(true); 

    System.out.println("cancelled: " + future.isCancelled() + "done: " + future.isDone()); 

    executorService.shutdown(); 

    try { 
     System.out.println("try to terminate: " + executorService.awaitTermination(60, TimeUnit.SECONDS)); 
    } catch (Exception ex) { 
     // ignore 
    } 
} 

但是它看起來像awaitTermination返回false。有沒有辦法讓我來檢查爲什麼ExecutorService不會終止?我能弄清楚哪些線程仍在運行?

+0

'future.cancel(true)'實際上中斷了線程。但是這隻會打開'thread.isInterrupted()'標誌。你將需要測試它或者介意你的'InterruptedException's。 – Gray

+0

我可以通過任何方式調用thread.stop()? – Popcorn

+0

'thread.stop()'已棄用。請參閱@ Marko的答案。 – Gray

回答

1

沒有安全的方法來停止正在運行的線程而不會影響其他進程的穩定性。這就是很久以前Thread#stop已被棄用的原因,以及爲什麼Executor Services只使用軟協作機制。

您的線程將不得不主動檢查是否已請求中斷,並在結束之前執行正確的清理。或者,該線程將調用一些可中斷的JDK方法,這將拋出InterruptedException,這樣就可以正確地兌現和結束自己。

+0

+1你可以用'while(!Thread.currentThread()。isInterrupted()))'來檢查中斷位。 – Gray

+0

如果我的線程執行的計算阻塞了什麼?如何在這種情況下主動檢查中斷?我編輯了我的HelloWorker來展示一個例子。 – Popcorn

+1

這是一個經典的問題:你不能吃你的蛋糕,也不能吃它。如果線程被強行阻止,沒有進程隔離來保護所有其他線程免受損害。如果你的longnigg計算方法不能偶爾檢查中斷標誌,那麼你將無法安全地停止線程。 –

相關問題