Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java UncaughtExceptionHandler with ExecutorService

farenda 2015-10-28 3

Problem:

How to set UncaughtExceptionHandler per Java Thread when working with Executorservice? This can be tricky, but we show a nice solution using ThreadFactory with ExecutiorService.

Solution:

In the previous post (Java Thread UncaughtExceptionHandler) we’ve shown how to set UncaughtExceptionHandler when creating threads manually. In this post we’ll show how to do it when one wants to use ExecutorService for threads management.

To be able set UncaughtExceptionHandler per thread we need to create a Java ThreadFactory, which will create threads and set the handler for each Thread. Then we just stop ExecutorService and print all errors collected by the exception handler:

package com.farenda.java.lang;

import com.farenda.java.lang.ThreadUncaughtExceptionHandlerExample.MyUncaughtExceptionHandler;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class ThreadUncaughtExceptionHandlerExecutorService {

    public static class ExceptionalTask implements Runnable {
        private static int ntasks = 0;
        private int taskId = ++ntasks;

        @Override
        public void run() {
            System.out.println("Starting work in thread: " + taskId);
            try {
                TimeUnit.MILLISECONDS.sleep(200);
            } catch (InterruptedException e) {
                //ignore
            }
            if ((taskId % 2) == 0) {
                throw new RuntimeException("An Exception that ends task: " + taskId);
            } else {
                System.out.printf("Task %d finished normally.%n", taskId);
            }
        }
    }

    private static class CaughtExceptionsThreadFactory implements ThreadFactory {
        private MyUncaughtExceptionHandler handler = new MyUncaughtExceptionHandler();

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setUncaughtExceptionHandler(handler);
            return t;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CaughtExceptionsThreadFactory threadFactory = new CaughtExceptionsThreadFactory();
        ExecutorService executor = Executors.newCachedThreadPool(threadFactory);

        System.out.println("Executing tasks:");
        for (int i = 0; i < 5; ++i) {
            executor.execute(new ExceptionalTask());
        }

        System.out.println("Shutting down the executor.");
        // we'll wait for two seconds, just to have clean output
        executor.awaitTermination(2, TimeUnit.SECONDS);

        printResults(threadFactory.handler);
    }

    private static void printResults(MyUncaughtExceptionHandler handler) {
        System.out.println("\nCaught errors:");
        handler.getErrors().forEach(System.out::println);
    }
}

Here’s the output of running the above code:

Executing tasks:
Starting work in thread: 1
Starting work in thread: 2
Starting work in thread: 3
Starting work in thread: 4
Shutting down the executor.
Starting work in thread: 5
Task 1 finished normally.
Thread Thread-3 hit by exception java.lang.RuntimeException: An Exception that ends task: 4.
Thread Thread-1 hit by exception java.lang.RuntimeException: An Exception that ends task: 2.
Task 5 finished normally.
Task 3 finished normally.

Caught errors:
Thread Thread-3 hit by exception java.lang.RuntimeException: An Exception that ends task: 4.
Thread Thread-1 hit by exception java.lang.RuntimeException: An Exception that ends task: 2.

Pretty straightforward. The only thing to remember is that when we want to set UncaughtExceptionHandler per thread we have to provide own ThreadFactory, in which we do that. Another approach would be to use static Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler) to set the default handler for all threads. Chosen solution depends on what you need.

Share with the World!
Categories Java Tags java, java-concurrency
Previous: Java Thread UncaughtExceptionHandler
Next: Java Thread Join Example

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2022

sponsored
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.Ok