Dans le code ci-dessous, j'attrape une expression temporelle après 100 secondes comme prévu. À ce stade, je m'attendrais à ce que le code quitte le Main et le programme de résilier, mais il conserve l'impression à la console. Comment puis-je obtenir la tâche pour arrêter d'exécuter après le délai d'attente?
3 Réponses :
Une fois que vous avez attrapé la timeoutException, vous devez appeler la méthode Annuler (TRUE) de votre tâche ... p>
ou fermez votre exécutorservice en appelant shutdownow () ... p>
ou quittez la machine virtuelle en appelant system.exit (0) p>
en fonction de vos besoins p>
Vous devez annuler votre tâche sur le délai d'attente (et interrompre son fil). C'est ce que annuler (true) code> est pour. : private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();
private static <T> T timedCall(FutureTask<T> task, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
THREAD_POOL.execute(task);
return task.get(timeout, timeUnit);
}
public static void main(String[] args) {
try {
FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
for (int i=0; i < 1000000; i++) {
if (Thread.interrupted()) return 1;
System.out.println(new java.util.Date());
Thread.sleep(1000);
}
return 0;
}
});
int returnCode = timedCall(task, 100, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
task.cancel(true);
}
return;
}
! Task.Cancéd () devrait être! Iscancéd () comme Djna a écrit à l'origine
Je pense que c'est beaucoup mieux d'utiliser des interruptions. Premièrement, votre code appelable n'a pas besoin de savoir sur tâche code> du tout. Deuxièmement, lorsque vous utilisez diverses opérations de blocage dans votre code appelable (comme thread.sleep () code>), ceux-ci ne réagiront pas à la tâche.iscellé (), mais réagit généralement aux interruptions. Ainsi, en utilisant annuler (true) code> et que votre code conscient des interruptions est généralement le meilleur moyen de le faire. (Votre code sera également plus général, car le mécanisme d'interruption est si largement utilisé en Java)
Je suppose que mon point est que "l'interruption est un mécanisme coopératif". ( ibm.com/developerworks/java/library/j-jtp05236.html )
@Peter bel article! J'ai changé la réponse en conséquence.
Le code Cleary n'est pas testé. Tâche Code> serait indéfini dans Catch code> bloc
Votre appelable doit être capable de s'arrêter rapidement, en cas de besoin.
Votre code: p> est déjà capable de le faire grâce à l'appelant Vous devez appeler Mon conseil est d'en savoir plus sur le mécanisme d'interruption (c'est un excellent article: traiter avec une exception interrompue ) et l'utiliser. p> p> .sleep () code>. Point est que futuetask.cancel (true) code> interrompt l'autre thread et que votre code doit réagir à cette interruption. thread.sleep () code> Est-ce que cela. Si vous n'avez pas utilisé thread.sleep () code> ou un autre code de blocage interruptible, vous devez vérifier thread.CurrentThread (). Isinterrupted () code> par vous-même, et quitte Dès que possible (par exemple, en lancant nouvelle interruptedexception () code>) lorsque vous trouvez que cela soit vrai. p> futuetask.cancel (vrai); < / Code> à partir de votre gestionnaire d'exception pour annuler et interrompre le fil qui exécute votre tâche. P>