我使用ExecutorService排队了一系列作业。如果用户点击“取消”,那么我需要通知这些工作他们应该尽快停止。但是,有时它们处于代码的关键部分,必须在父线程继续之前完成。我怎样才能做到这一点?我不想使用自己的取消标志,因为这不会导致睡眠/等待退出。
我认为这段代码可行,但它没有按照我的意愿行事:
while( true ) {
//Do this in a loop. If our thread is interrupted, we call cancel on the threads (to try to get them to hurry up by skipping non-essential stuff), but we still need to wait for them to finish.
try {
for( Future<Void> future : futures ) {
future.get(); //I thought that this would continue waiting, even if I call cancel, but it doesn't. How can I wait for the future to finish?
}
break; //OK, everything is finished, exit the wait loop.
} catch( InterruptedException e ) {
wasInterrupted = true; //We'll rethrow the exception laster as an AbortException.
//Need to wait for futures to finish, even if it's canceled.
log.info( "Attempting to interrupt threads that are reading changes..." );
for( Future<Void> future : futures ) {
future.cancel( true ); //I want to tell the threads to 'hurry up' and skip non-essential stuff.
}
} catch( ExecutionException e ) {
throw e.getCause();
}
}
//I shouldn't get to this line until all futures have finished!
答案 0 :(得分:4)
如何打断未来,但还是等待它完成?
有趣的问题。您的代码无法正常运行,因为当您取消Future
时,如您所发现的那样,您无法再次呼叫get()
,因为这会引发CancellationException
。
如果我理解你的要求:
sleep
,wait
等。要做的事情是不在这里使用Future
。相反,使用您自己的工作包装器并等待ExecutorService
本身以executorService.awaitTermination(...)
结束。
如果您需要任务的结果,那么您的Runnable
包装器类将保存计算结果并具有boolean done
标志。等待线程将等待每个Runnable
将其done
标志设置为true。当包装器完成其run()
方法时,它会自行设置done
和notify()
。它需要在finally
块中执行此操作。
如果等待线程被中断,它将调用executorService.shutdownNow(true)
来中断所有线程,但会继续循环等待它们完成。
类似的东西。
答案 1 :(得分:0)
“尽快”表示线程应该知道何时退出
无论如何,您可以使用中断线程策略
if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();
另见
http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-