2013-12-19 57 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计算方法不能偶尔检查中断标志,那么你将无法安全地停止线程。 –

相关问题