HellishHeat
HellishHeat

Reputation: 2491

What Happens when a thread doesn't throw an exception?

I notice, in this javadoc, https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html that an UncaughtExceptionHandler is used for when an exception occurs but is not caught. But, will that thread fail quietly? I guess so, because it is going about its business asynchronously, but I'm investigating a related issue with one of our processes, and am surprised at only being aware of this now, 10+ years into my career.

Upvotes: 1

Views: 783

Answers (3)

HellishHeat
HellishHeat

Reputation: 2491

I finally got to the bottom of my specific problem. It was due to shoddy error handling, allowing the thread to fail quietly:

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {

            public void run() {
                try {
                    //do some stuff
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("done-worker thead");
                throw new RuntimeException("purposeful!");
            }
        };
        t.setUncaughtExceptionHandler(
                (thread, throwable) -> System.out.println("main thread; uncaugh exception from worker threadt: " + throwable.getMessage()));
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done-main thead");
    }
}

In doing "some stuff", the application hit an OutOfMemoryError, which is not, strictly seaking, an Exception. Changing the catch statement to catch(Throwable t), solved it.

Upvotes: 0

pveentjer
pveentjer

Reputation: 11307

The thread will fail quietly :)

More than a decade ago a ran into a similar problem. The performance of a system started to degrade over time. Eventually, I identified the cause: an exception was thrown in a worker thread in some custom thread pool and the worker thread was terminated. So over time, the number of live threads in the thread pool started to decrease and performance dropped.

The problem was hidden by the fact that there was no logging of the exception.

[edit]

My answer above is not correct. This is demonstrated in the below example:

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            public void run(){
                throw new RuntimeException();
            }
        };
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done");
    }
}

When the code is run, the following output is shown:

Exception in thread "Thread-0" java.lang.RuntimeException
    at Main$1.run(Main.java:8)
done

So the exception is Logged.

Upvotes: 3

HellishHeat
HellishHeat

Reputation: 2491

Based on @pveentjar's updated answer I ran the following code:

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {

            public void run() {
                throw new RuntimeException("purposeful!");
            }
        };
        t.setUncaughtExceptionHandler((thread, throwable) -> System.out.println("uncaught: " + throwable.getMessage()));
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done");
    }
}

, and ascertained that the uncaughtExceptionHandler seems to catch an exception from the thread that uses it, allowing the developer to do what they want with it, but that leaves the question, why bother with that handler, if not to save a system from a silent failure? output:

uncaught: purposeful!
[a pause of approximately ten seconds]
done

Upvotes: 0

Related Questions