Exception handling in ThreadPools

后端 未结 6 1832
予麋鹿
予麋鹿 2020-12-23 16:18

I have a ScheduledThreadPoolExecutor that seems to be eating Exceptions. I want my executor service to notify me if a submitted Runnable throws an exception.

For ex

相关标签:
6条回答
  • 2020-12-23 17:03

    You can subclass ScheduledThreadPoolExecutor and override the afterExecute method to handle exceptions and errors for any kind of Runnable that you submit.

    0 讨论(0)
  • 2020-12-23 17:04

    Warning: This method is not applicable to scheduled thread pool executors. This answer has been undeleted for its relevance to other thread pool executors. See Willi's answer.

    Override the ThreadFactory to give Threads an 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-23 17:12

    You could also use a ThreadPoolTaskScheduler from the Spring Framework, which exposes a method to set an error handler and does all the wrapping for you. The default behavior depends on the type of task:

    If the provided ErrorHandler is not null, it will be used. Otherwise, repeating tasks will have errors suppressed by default whereas one-shot tasks will have errors propagated by default since those errors may be expected through the returned Future. In both cases, the errors will be logged.

    If you only want to use the wrapping part and not the TaskScheduler you can use

    TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask)
    

    which the TaskScheduler uses internally.

    0 讨论(0)
  • 2020-12-23 17:12

    Consider adding a static event in your ScheduledThreadPoolExecutor class that any of your tasks can call if an exception is thrown. That way, you can leverage that event to capture and handle the exceptions that occur within your threads.

    0 讨论(0)
  • 2020-12-23 17:15

    I wrote a small post about this problem a while ago. You have two options:

    1. Use the solution provided by Colin Herbert or
    2. use a modified version of Mark Peters solution but instead of assigning a UncaughtExceptionHandler you wrap each submitted runnable into a runnable of your own which executes (calls run) the real runnable inside a try-catch-block.

    EDIT
    As pointed out by Mark, it's important to wrap the Runnable passed to ScheduledExecutorService instead of the one passed to the ThreadFactory.

    0 讨论(0)
  • You can use the get() method from the Future you're getting by calling scheduleAtFixedRate(). It will throw an ExecutionException if an exeception occurred during the thread execution.

    0 讨论(0)
提交回复
热议问题