如果通过 future.get(timeout, TimeUnit.SECONDS) 取消 Callable,是否会调用线程中的 finally block ?
class MyCallable implements Callable<Future<?>>{
public Future<?> call(){
Connection conn = pool.getConnection();
try {
...
} catch(CatchExceptions ce){
} finally {
conn.close();
}
}
}
...
future.get(executionTimeoutSeconds, TimeUnit.SECONDS);
我知道finally总会被调用,但我猜我遗漏了一些关于线程如何中断的信息。这是我运行的测试,没有显示我的finally block 被解雇。
@Test
public void testFuture(){
ExecutorService pool = Executors.newFixedThreadPool(1);
try {
pool.submit(new TestCallable()).get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
class TestCallable implements Callable<Void> {
@Override
public Void call() throws Exception {
try{
while(true){
Thread.sleep(3000);
break;
}
} catch (Exception e){
System.out.println("EXCEPTION CAUGHT!");
throw e;
} finally {
System.out.println("FINALLY BLOCK RAN!");
}
}
}
看起来如果我添加awaitTermination它就会运行。 该测试通过...
public void testFuture(){
ExecutorService pool = Executors.newFixedThreadPool(1);
try {
pool.submit(new TestCallable()).get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
try {
pool.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
请您参考如下方法:
future.get(...)
不取消线程。它只等待线程完成,如果等待超时,则抛出 TimeoutException
。
future.cancel(true)
将导致线程中断。这可能会也可能不会阻止您的线程处理。这取决于您的 try ...
部分中发生的情况。例如,Thread.sleep(...)
、Object.wait(...)
和其他方法在线程运行时抛出 InterruptedException
被中断。否则,您需要检查线程中断标志
if (Thread.currentThread().isInterrupted()) {
// maybe stop the thread or whatever you want
return;
}
如果进入 try
block ,则 finally
block 总是被调用(无论是否中断),除非出现某种 JVM 错误和崩溃。我怀疑你的线程根本没有被中断,所以只是继续运行。