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 Thread UncaughtExceptionHandler

farenda 2015-10-26 0

Problem:

How to handle exceptions in Java Thread? Since Java 5 the way to go is Thread UncaughtExceptionHandler, which we’re going to show in this post.

Solution:

In the below code we create and run a Thread that will throw an exception. When we try to catch the exception in the code that starts the exception nothing happens – the exception cannot be caught this way:

public static void main(String[] args) {
    try {
        new ExceptionalThread().start();
    } catch (Exception e) {
        System.out.println("Got exception: " + e);
    }
}

ExceptionalThread class is defined in the code below.

Here’s the result of running the above code:

Starting work in thread: 10
Exception in thread "Thread-0" java.lang.RuntimeException: An Exception that ends the thread: 10
      at com.farenda.java.lang.ThreadUncaughtExceptionHandlerExample$ExceptionalThread.run(ThreadUncaughtExceptionHandlerExample.java:31)

As you can see there’s no “Got exception” in the output and the exception got printed to standard output, which is the default behavior.

To fix that and handle exceptions uncaught by threads Java provides a mechanism of UncaughtExceptionHandler. You can obtain default handler using static method Thread.getDefaultUncaughtExceptionHandler(). The default handler is fine for many situations, but sometimes (for example in GUI application) we would like to collect such information and act appropriately. To do that you can set own handler for threads. It can be done in a few ways:

  • void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
    That allows to set per thread handler.
  • static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
    To set default handler for Threads, which will be active when they don’t have their own handler.

In the following example we’ll show both ways – per thread and default. Our MyUncaughtExceptionHandler just collects thrown exceptions for further processing:

package com.farenda.java.lang;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class ThreadUncaughtExceptionHandlerExample {

    public static class MyUncaughtExceptionHandler
            implements Thread.UncaughtExceptionHandler {

        private List<String> errors = new LinkedList<>();

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            String message = String.format("Thread %s hit by exception %s.",
                    t.getName(), e.toString());
            System.out.println(message);
            errors.add(message);
        }
    }

    private static class ExceptionalThread extends Thread {
        @Override
        public void run() {
            System.out.println("Starting work in thread: " + getId());
            try {
                TimeUnit.MILLISECONDS.sleep(200);
            } catch (InterruptedException e) {
                //ignore
            }
            // throw an exception when thread ID is even:
            if ((getId() % 2) == 0) {
                throw new RuntimeException("An Exception that ends the thread: "
                        + getId());
            } else {
                System.out.printf("Thread %d finished normally.%n", getId());
            }
        }
    }

    public static void main(String[] args) {
        MyUncaughtExceptionHandler handler = new MyUncaughtExceptionHandler();

        startThreadsWithPerThreadHandler(handler);
        printResults(handler);

        System.out.println("\nClearing errors in handler.\n");
        handler.errors.clear();

        startThreadsWithDefaultHandler(handler);
        printResults(handler);
    }

    private static void startThreadsWithDefaultHandler(
            MyUncaughtExceptionHandler handler) {
        System.out.println("Setting default uncaught exception handler.");
        Thread.setDefaultUncaughtExceptionHandler(handler);
        System.out.println("Starting threads");
        for (int i = 0; i < 5; ++i) {
            new ExceptionalThread().start();
        }
    }

    private static void startThreadsWithPerThreadHandler(
            MyUncaughtExceptionHandler handler) {
        System.out.println("Starting threads with per thread uncaught exception handler");
        for (int i = 0; i < 5; ++i) {
            ExceptionalThread command = new ExceptionalThread();
            command.setUncaughtExceptionHandler(handler);
            command.start();
        }
    }

    private static void printResults(MyUncaughtExceptionHandler handler) {
        try {
            System.out.println("Waiting a bit for threads to finish...");
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            // ignore
        }

        System.out.println("\nCaught errors:");
        handler.errors.forEach(System.out::println);
    }
}
&#91;/sourcecode&#93;

<p> The code is straightforward. In <b>startThreadsWithDefaultHandler()</b> we set default handler for all threads and in <b>startThreadsWithPerThreadHandler()</b> we set it per thread basis, so we could set different handlers for them. </p>

<p> And the result of running the above code: </p>


Starting threads with per thread uncaught exception handler
Starting work in thread: 10
Starting work in thread: 11
Starting work in thread: 12
Starting work in thread: 13
Waiting a bit for threads to finish...
Starting work in thread: 14
Thread 11 finished normally.
Thread Thread-4 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 14.
Thread 13 finished normally.
Thread Thread-2 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 12.
Thread Thread-0 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 10.

Caught errors:
Thread Thread-4 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 14.
Thread Thread-2 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 12.
Thread Thread-0 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 10.

Clearing errors in handler.

Setting default uncaught exception handler.
Starting threads
Starting work in thread: 16
Starting work in thread: 17
Starting work in thread: 15
Starting work in thread: 18
Waiting a bit for threads to finish...
Starting work in thread: 19
Thread 17 finished normally.
Thread 15 finished normally.
Thread 19 finished normally.
Thread Thread-6 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 16.
Thread Thread-8 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 18.

Caught errors:
Thread Thread-6 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 16.
Thread Thread-8 hit by exception java.lang.RuntimeException: An Exception that ends the thread: 18.

As you can see even threads thrown exceptions, which have been collected in MyUncaughtExceptionHandler error list. The list have been printed in printResults() method, but we could process them and show to users or create a report and send an email to admins.

In this post we haven’t covered one thing – how to set UncaughtExceptionHandler when ExecutorService is used. We’ll show that in the next post, so stay tuned. :-)

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

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