Welcome to The ninth article in a series on Concurrency.

In this article, I’ll show you how exceptions are handled in threads and how to use uncaughtExceptionHandler.

Where did the exception in the new thread go

In the process of application execution, it is inevitable that various unexpected errors will occur. If we do not capture and handle the errors, it will directly affect the running result of the application or even cause the application to crash. In application exception handling, multi-threaded exception handling is important and easy to make mistakes.

Next, we simulate a common multithreaded exception handling method through a piece of code.

In the following code, we create a new thread in the main thread, nezhaThread, and expect to catch the exception thrown by the new thread in the main thread:

 public static void main(String[] args) {
        Thread neZhaThread = new Thread() {
            public void run(a) {
                throw new RuntimeException("I'm Nezha, I'm under siege!"); }};// Try to catch an exception thrown by the thread
        try {
            neZhaThread.start();
        } catch (Exception e) {
            System.out.println("Receive hero exception:"+ e.getMessage()); }}Copy the code

The running results are as follows:

The Exception in the thread "thread - 0" Java. Lang. RuntimeException: I am which zha, I siege! at cn.tao.king.juc.execises1.ExceptionDemo$1.run(ExceptionDemo.java:7) Process finished with exit code 0Copy the code

For multithreaded novices, this may not be straightforward to see. However, as you can see from the result of the run, the “receive hero exception” keyword is not printed. That is, the main thread does not catch exceptions for the new thread. So why?

To understand this, start with the nature of threading. In Java, each thread runs a piece of code that runs independently, and if we don’t actively provide mechanisms for inter-thread communication and collaboration, they are isolated from each other.

In other words, each thread has to handle all tasks, including handling exceptions, in its own closed loop, and if something goes wrong but you don’t actively handle exceptions, they will self-destruct according to the established process.

Two, multithreaded in the exception handling

1. View the exception handling from the main thread

To understand error handling in multiple threads, let’s first look at how common main threads handle errors, since a single main thread is easier to understand than multiple threads.

 public static void main(String[] args) {
        throw new NullPointerException();
    }
Copy the code

Obviously, the above code will throw the following error message:

Exception in thread "main" java.lang.NullPointerException
	at cn.tao.king.juc.execises1.ExceptionDemo.main(ExceptionDemo.java:21)
Copy the code

You are familiar with stack information similar to null pointer errors. Handling such exceptions in the main thread is as simple as writing a try and catch block. In addition to this, we can also define uncaughtExceptionHandler to handle exceptions in the main thread.

 public static void main(String[] args) {
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        throw new NullPointerException();
    }

    // Custom error handling
    static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("Mistake! Thread name:" + t.getName() + Error message:+ e.getMessage()); }}Copy the code

The output is as follows:

Make a mistake! Thread name: main, error message: NULL Process Finished with exit code 1Copy the code

You see, we’ve already caught the exception. However, you may wonder why the Thread. UncaughtExceptionHandler can custom error handling? Speaking of which, we have to mention the exception handling in Java, as shown in the following figure:

In Java, we often see null pointer error stack information, but the stack is actually printed by the thread “out of necessity” in case of an error. As can be seen from the picture:

  • When a thread fails, it first checks to see if the current thread specifies an error handler.
  • If the current thread does not have an error handler specified, it continues to check if its thread group is specified (note that each thread has a thread group).
  • If the thread group of the current thread is not specified, then check whether the parent thread is specified.
  • If the parent thread also does not specify an error handler, the last check is to see if the default handler is set.
  • If the default handler is also not set, you will have to output the wrong stack information.

2. Exception handling between multiple threads

Remember, the main thread is also a thread, so once you understand how errors are handled in the main thread, you also understand how exceptions are handled in child threads, which are the same as in the main thread. In the main Thread, we can through the Thread. SetDefaultUncaughtExceptionHandler to set a custom exception handler. In a new child thread, we can specify the exception handler directly through the thread object. For example, we set the exception handler for the previous neZhaThread thread:

neZhaThread.setName("Which zha");
neZhaThread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Copy the code

Then, after setting the handler, the thread exception information is output as follows:

Make a mistake! Thread name: Nezha, error message: I am Nezha, I am under siege! Process finished with exit code 0Copy the code

You see, by defining uncaughtExceptionHandler, we have caught and handled the exception thrown by the new thread.

3. Understand UncaughtExceptionHandler

From the code above, you should have an intuitive understanding of the use of UncaughtExceptionHandler. In Java, UncaughtExceptionHandler is used when a thread terminates unexpectedly and unexpectedly. When a thread throw an unhandled exception, for some reason the JVM in the virtual machine will be able to pass a thread getUncaughtExceptionHandler query error handler that thread, the thread and exception information passed as a parameter in the past. If the thread does not specify an error handler, the process shown in the figure above continues.

3. Define the three layers of uncaughtExceptionHandler

1. Define the default exception handler

The default error handler can be used as the underlying handler for thread exceptions, and can be used when no exception handler is specified for a thread or thread group.

 Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Copy the code

2. Customize a specific exception handler

If a thread needs a specific handler, it’s a good idea to specify an exception handler through a thread object. Of course, this exception handler cannot be shared with other threads.

neZhaThread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Copy the code

3. The ThreadGroup inheritance

You can reset the exception handler logic for the current ThreadGroup by inheriting ThreadGroup and overriding uncaughtException. Note, however, that overwriting thread groups is uncommon and should be used with caution.

public class MyThreadGroupDemo  extends ThreadGroup{
    public MyThreadGroupDemo(String name) {
        super(name);
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        // Override the exception handling logic for the thread group here
        System.out.println("Mistake! Thread name:" + t.getName() + Error message:+ e.getMessage()); }}Copy the code

summary

That’s all for thread exception handling. In this article we introduce how to handle multi-threaded exceptions and the use of uncaughtExceptionHandler. For multithreaded exception handling, remember:

  • Exceptions within the thread should be resolved internally as much as possible;
  • Cannot be used if the main thread needs to catch subthread exceptionstry,catch, but to useuncaughtExceptionHandler. Of course, the main thread will not be able to catch exceptions that have already been caught inside the child thread.

At the end of the text, congratulations on your another star ✨

The teacher’s trial

  • Write code to understand and experience uncaughtExceptionHandler usage.

Further reading and references

  • “King concurrent course” outline and update progress overview

About the author

Pay attention to the public number [technology 8:30], timely access to the article updates. Pass on quality technical articles, record the coming-of-age stories of ordinary people, and occasionally talk about life and ideals. 8:30 in the morning push author quality original, 20:30 in the evening push industry depth good article.

If this article is helpful to you, welcome to like, follow, supervise, we together from bronze to king.