46 votes

Gestion des exceptions dans ThreadPools

J'ai un ScheduledThreadPoolExecutor qui semble manger des Exceptions. Je veux que mon exécuteur testamentaire de service à m'avertir si un soumis Exécutable, déclenche une exception.

Par exemple, je voudrais le code ci-dessous pour à tout le moins l'impression de la IndexArrayOutOfBoundsException la stackTrace

threadPool.scheduleAtFixedRate(
  new Runnable() {
    public void run() {
      int[] array = new array[0];
      array[42] = 5;
    }
  },
  1000,
  1500L,
  TimeUnit.MILLISECONDS);

Que d'un côté de la question. Est-il possible d'écrire un général try catch block pour un ScheduledThreadPoolExecutor?

//////////LA FIN DE LA QUESTION D'ORIGINE //////////////

Comme l'a suggéré l'suivantes Décorateur fonctionne bien.

public class CatcherTask implements Runnable{

    Runnable runMe;

    public CatcherTask(Runnable runMe) {
        this.runMe = runMe;
    }

    public void run() {
        try {
            runMe.run();
        } catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

24voto

whiskeysierra Points 2175

J'ai écrit un petit post sur ce problème il y a longtemps. Vous avez deux options:

  1. Utiliser la solution de Colin Herbert ou
  2. utiliser une version modifiée de Mark Peters solution mais au lieu d'attribuer un UncaughtExceptionHandler vous envelopper chaque soumis praticable dans un exécutable de votre propre qui exécute (appels run) le vrai praticable à l'intérieur d'un try-catch-bloc.

MODIFIER
Comme souligné par la Marque, il est important pour envelopper l' Runnable passée de ScheduledExecutorService au lieu de celui passé à l' ThreadFactory.

13voto

Mark Peters Points 42201

Avertissement : cette méthode n'est pas applicable aux exécuteurs de pool de threads planifiés . Cette réponse a été annulée pour sa pertinence pour les autres exécuteurs de pool de threads. Voir la réponse de Willi .

Remplacez le ThreadFactory pour donner aux threads un UncaughtExceptionHandler:

 ThreadPoolExecutor exec = new ThreadPoolExecutor...;

exec.setThreadFactory(new ExceptionCatchingThreadFactory(exec.getThreadFactory()));
//go on to submit tasks...


private static class ExceptionCatchingThreadFactory implements ThreadFactory {
    private final ThreadFactory delegate;

    private ExceptionCatchingThreadFactory(ThreadFactory delegate) {
        this.delegate = delegate;
    }

    public Thread newThread(final Runnable r) {
        Thread t = delegate.newThread(r);
        t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();  //replace with your handling logic.
            }
        });
        return t;
    }
}
 

5voto

Colin Hebert Points 40084

Vous pouvez utiliser la méthode get() partir du Future que vous obtenez en appelant scheduleAtFixedRate() . Il lancera un ExecutionException si une exception s'est produite pendant l'exécution du thread.

3voto

boberj Points 201

Vous pouvez également utiliser un ThreadPoolTaskScheduler à partir du Framework Spring, qui expose une méthode pour définir un gestionnaire d'erreur et la ligne pour vous. Le comportement par défaut dépend du type de tâche:

Si la ErrorHandler n'est pas null, il sera utilisé. Sinon, répéter les tâches ont des erreurs supprimée par défaut alors que les one-shot tâches auront erreurs propagées par défaut dans la mesure où ces erreurs peuvent être attendus par le retour de l' Future. Dans les deux cas, les erreurs seront enregistrées.

Si vous souhaitez uniquement utiliser l'emballage et pas l' TaskScheduler vous pouvez utiliser

TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask)

qui l' TaskScheduler utilise en interne.

-1voto

Michael Points 1649

Envisagez d'ajouter un événement statique dans votre classe ScheduledThreadPoolExecutor que n'importe laquelle de vos tâches peut appeler si une exception est levée. De cette façon, vous pouvez tirer parti de cet événement pour capturer et gérer les exceptions qui se produisent dans vos threads.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X