En el siguiente código, estoy atrapando una TimeoutException después de 100 segundos como estaba previsto. En este punto, esperaría que el código salga de main y que el programa finalice, pero sigue imprimiéndose en la consola. ¿Cómo hago para que la tarea deje de ejecutarse después del tiempo de espera?¿Cómo consigo que FutureTask regrese después de TimeoutException?
private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();
private static <T> T timedCall(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
FutureTask<T> task = new FutureTask<T>(c);
THREAD_POOL.execute(task);
return task.get(timeout, timeUnit);
}
public static void main(String[] args) {
try {
int returnCode = timedCall(new Callable<Integer>() {
public Integer call() throws Exception {
for (int i=0; i < 1000000; i++) {
System.out.println(new java.util.Date());
Thread.sleep(1000);
}
return 0;
}
}, 100, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
! Task.cancelled() debería ser! IsCancelled() como djna escribió originalmente – Zed
Creo que es mucho mejor usar interrupciones. En primer lugar, su código invocable no necesita saber nada acerca de 'task'. Segundo, cuando usa varias operaciones de bloqueo en su código invocable (como 'Thread.sleep()'), estas no reaccionarán a task.isCancelled(), pero generalmente reaccionan a interrupciones. Entonces, usar 'cancel (true)' y hacer que tu código sea consciente de las interrupciones suele ser la mejor manera de hacerlo. (Su código también será más general, porque el mecanismo de interrupciones es ampliamente utilizado en Java) –
Creo que mi punto es que "La interrupción es un mecanismo cooperativo". (http://www.ibm.com/developerworks/java/library/j-jtp05236.html) –