1
如果通過future.get(timeout,TimeUnit.SECONDS)取消Callable,是否會調用帶線程的finally塊?Futures,TimeoutException和可變終止塊
class MyCallable implements Callable<Future<?>>{
public Future<?> call(){
Connection conn = pool.getConnection();
try {
...
} catch(CatchExceptions ce){
} finally {
conn.close();
}
}
}
...
future.get(executionTimeoutSeconds, TimeUnit.SECONDS);
我知道終於總是會被調用,但我猜我缺少一些關於線程是如何中斷的。這是我跑過的一個測試,沒有顯示我的最後一塊被解僱。
@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!");
}
}
}
看起來像是我添加了await Termination它運行。 該測試通過...
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();
}
}
只是有點評論:finally塊總是被調用,如果try塊開始執行。如果線程沒有進入try塊並被終止,那麼最終當然不會被調用。 – kornero
好點@ kornero。我調整了我的答案。 – Gray