Подтвердить что ты не робот

Обработка исключений в ThreadPools

У меня есть ScheduledThreadPoolExecutor, который, кажется, есть Исключения. Я хочу, чтобы служба-исполнитель уведомила меня, если отправленное Runnable вызывает исключение.

Например, мне бы хотелось, чтобы код ниже, по крайней мере, напечатал IndexArrayOutOfBoundsException stackTrace

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

Как побочный вопрос. Есть ли способ написать общий блок catch try для ScheduledThreadPoolExecutor?

//////////КОНЕЦ ОРИГИНАЛЬНОГО ВОПРОСА //////////////

Как было предложено, следующий Decorator хорошо работает.

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();
        }
    }
}
4b9b3361

Ответ 1

Я написал небольшую сообщение об этой проблеме некоторое время назад. У вас есть два варианта:

  • Используйте решение, предоставленное Колином Гербертом или
  • используйте модифицированную версию решения Mark Peters , но вместо назначения UncaughtExceptionHandler вы завершаете каждый представленный runnable в исполняемый файл, который выполняется (вызывает run) реальный runnable внутри блока try-catch.

ИЗМЕНИТЬ
Как отметил Марк, важно обернуть Runnable, переданный в ScheduledExecutorService, а не тот, который был передан в ThreadFactory.

Ответ 2

Предупреждение. Этот метод не применим к запланированным исполнителям пулов потоков. Этот ответ был восстановлен за его соответствие другим исполнителям пула потоков. См. Ответ Вилли.

Переопределите ThreadFactory, чтобы предоставить Threads 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;
    }
}

Ответ 3

Вы можете использовать метод get() из Future, который вы получаете, вызывая scheduleAtFixedRate(). Он выкинет ExecutionException, если во время выполнения потока произошла утечка.

Ответ 4

Вы также можете использовать ThreadPoolTaskScheduler из Spring Framework, который предоставляет метод для установки обработчика ошибок и выполняет все обертывание для вас. Поведение по умолчанию зависит от типа задачи:

Если предоставленный ErrorHandler не является нулевым, он будет использоваться. В противном случае повторяющиеся задачи будут иметь ошибки, подавленные по умолчанию, тогда как задачи с одним выстрелом будут иметь ошибки, распространяемые по умолчанию, поскольку эти ошибки можно ожидать через возвращаемый Future. В обоих случаях ошибки будут регистрироваться.

Если вы хотите использовать только часть обертки, а не TaskScheduler, вы можете использовать

TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask)

который использует TaskScheduler внутри.

Ответ 5

Вы можете подклассифицировать ScheduledThreadPoolExecutor и переопределить метод afterExecute для обработки исключений и ошибок для любого вида Runnable, который вы отправляете.

Ответ 6

Подумайте о добавлении статического события в класс ScheduledThreadPoolExecutor, который может вызвать любая из ваших задач при вызове исключения. Таким образом, вы можете использовать это событие для захвата и обработки исключений, возникающих в ваших потоках.