Question

My consumer doesn't work the way I expect it to. Below is an sscce of what happens in my real program.

  • Expected:
    1. Print In finally!
    2. Print About to print stacktrace
    3. Print a NullPointerException stacktrace.
  • Actual:
    1. Print In finally!
    2. Hang, in sun.misc.Unsafe

Program:

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class ThreadTest implements Runnable {
    public static void main(String... args) {
        ExecutorService service = Executors.newSingleThreadExecutor(new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread newThread = new Thread(r);
                        newThread.setUncaughtExceptionHandler(new MyExceptionHandler());
                        return newThread;
                    }
                });
        service.submit(new ThreadTest());
    }

    private static class MyExceptionHandler implements UncaughtExceptionHandler {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("About to print stacktrace");
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        Object foo = null;
        try {
            while(!Thread.interrupted()) {
                Thread.sleep(1000);
                System.out.println(foo.toString());
                System.out.println("After npe!");
            }
        } catch(InterruptedException e) {

        } finally {
            System.out.println("In finally!");
        }
    }
}
Was it helpful?

Solution

Runnables run inside an Executor don't really throw exceptions which will hit the thread's uncaught exception handler. Instead, the Runnable is wrapped with code which catches Throwable. This is so that a Future can return the exception that was thrown from the task.

as @Gray noted in the comments below, your program is "hanging" because the thread pool thread is keeping the program from exiting. your runnable has completed and the thread pool thread is just waiting for a new task. if you shutdown the thread pool, your program will complete normally (or make the thread pool threads daemon).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top