Attraper des exceptions de thread à partir de Java ExecutorService
Je travaille sur un framework de développement du logiciel pour le calcul parallèle JavaSeis.org. J'ai besoin d'un robuste mécanisme de signalement fil des exceptions. Au cours du développement, savoir où les exceptions sont venus de a haute valeur, donc je voudrais err sur le côté de la sur-production de rapports. Je tiens également à être en mesure de gérer Junit4 tests dans les threads. C'est l'approche ci-dessous raisonnable ou est-il un meilleur moyen ?
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThreadFailure {
public static void main(String[] args) {
int size = 1;
ExecutorService exec = Executors.newFixedThreadPool(size);
ThreadFailTask worker = new ThreadFailTask();
Future<Integer> result = exec.submit(worker);
try {
Integer value = result.get();
System.out.println("Result: " + value);
} catch (Throwable t) {
System.out.println("Caught failure: " + t.toString());
exec.shutdownNow();
System.out.println("Stack Trace:");
t.printStackTrace();
return;
}
throw new RuntimeException("Did not catch failure !!");
}
public static class ThreadFailTask implements Callable<Integer> {
@Override
public Integer call() {
int nbuf = 65536;
double[][] buf = new double[nbuf][nbuf];
return new Integer((int) buf[0][0]);
}
}
}
source d'informationauteur Chuck Mosher
Vous devez vous connecter pour publier un commentaire.
Je ne crois pas qu'il existe une "norme" hook " pour arriver à ces exceptions lors de l'utilisation de
submit()
. Toutefois, si vous avez besoin de soutiensubmit()
(ce qui semble raisonnable, étant donné que vous utilisez unCallable
), vous pouvez toujours placer l'Callables et Runnables :Bien sûr, cette méthode ne fonctionne que si vous êtes l'un des bâtiments de la
ExecutorService
en premier lieu. En outre, n'oubliez pas de remplacer tous les troissubmit()
variantes.Envisager la convocation d'
execute()
au lieu desubmit()
sur leExecutorService
. UnThread
invoqué avecexecute()
appeler leThread.UncaughtExceptionHandler
quand il échoue.Tout simplement faire un
ThreadFactory
qui installe unThread.UncaughtExceptionHandler
sur tous lesThreads
puis d'appeler votre travail avecexecute()
sur leExecutorService
au lieu desubmit()
.Jetez un oeil à cette liés à débordement de pile question.
Comme expliqué dans ce fil Quelle est la différence entre présenter et exécuter la méthode avec ThreadPoolExecutorexécution ne fonctionnera que si vous mettez en œuvre Exécutables, et pas Exigible à la commande exécuter ne peut pas renvoyer un Avenir.
Je pense que dans votre cas, vous devez construire le futur de l'objet de sorte qu'il peut accueillir l'exception de trucs aussi. Ainsi, en cas d'exception vous de construire le message d'erreur de l'objet.
Ma question initiale posée de savoir comment mettre en œuvre "robuste" thread de gestion des exceptions en Java ExecutorService. Grâce à Angelo et Greg pour les pointeurs sur la façon dont la gestion des exceptions fonctionne avec ExecutorService.submit() et de l'Avenir.get(). Mon révisé fragment de code est indiqué ci-dessous. Le point clé que j'ai appris ici, c'est que l'Avenir.get() les captures de toutes les exceptions. Si le thread a été interrompu ou annulé, vous obtenez l'exception appropriée, sinon, l'exception est enveloppé et re-jeté comme un ExecutionException.
Je n'ai pas eu beaucoup de chance avec les autres réponses, car j'avais besoin de l'exception de l'instance, lui-même, et pas seulement d'une impression de trace de la pile. Pour moi, la accepté de répondre impliquant ThreadPoolExecutor#afterExecute() de la question "Pourquoi est-UncaughtExceptionHandler pas appelé par ExecutorService?" travaillé.
Voir l'exemple de code suivant:
À la gestion des exceptions dans ExecutorService vous avez à prendre l'avantage de Appelable et Avenir.
S'il vous plaît regarder la vidéo ci-dessous pour plus de détails. Espérons que cela vous aidera à nos.
VIDÉO: Callable et Avenir(11 min)