More excellent articles.

“Microservices are not all, just a subset of a specific domain”

Selection and process should be careful, otherwise it will be out of control.

Out of all the monitoring components, there’s always one for you

What are we Developing with Netty?

This is probably the most pertinent Redis specification

Portrait of a Programmer: A Decade of Ups and Downs

Most useful series:

The Most Common Set of “Vim” Techniques for Linux Production

The most Common set of “Sed” Techniques for Linux Production

The Most Common Set of “AWK” Tips for Linux Production

If you agree with this knowledge, welcome to follow the wechat public account Xiaojie Taste

ID: xjjdog

Suppose we have a thread pool, and we submit many, many tasks to the thread pool because our program needs them, but none of these tasks do try catch for exceptions, and they all throw exceptions when they run. How does this affect the running of the thread pool?

The correct answer is: none. That’s not a good thing.

If you created a thread pool for developers to use, would you do something about it? Think about it for sure, otherwise what you’re offering someone else is questionable and ill-conceived. And the main developer of Java thread pools is Doug Lea. How do you think the code he developed allowed this to happen?

The problem is tricky because it sits in a corner and doesn’t come out when the program is running properly.

Problem analysis

Let’s take a look at how thread pools in Java run our submitted tasks. We won’t focus on the details here, but we’ll focus on the execution part of the task. Thread pools in Java use ThreadPoolExecutor, and the actual code execution is the runWorker method: Final void runWorker(Worker w)

As you can see, the program catches all exceptions, including Error, and passes any exceptions and the current task to the afterExecute method at the end of the program.

The afterExecute method in ThreadPoolExecutor does not have any implementation.

 protected void afterExecute(Runnable r, Throwable t) { }
Copy the code

There is a problem

Imagine the problem with this ThreadPoolExecutor approach?

This ensures that the submitted task that throws an exception will not affect the execution of other tasks, nor will it have any impact on the thread used to execute the task.

The problem is with the afterExecute method, which does nothing, so if our task throws an exception, we won’t know it right away. Even if it is detected, the abnormal information cannot be viewed.

So, as a good developer, you shouldn’t allow this to happen.

How to avoid this problem

The idea is simple.

1. Exceptions are caught and handled in submitted tasks, not thrown to the thread pool.

2. Exceptions are thrown to the thread pool, but we need to handle them in a timely manner.

Direct the catch

The first idea is simple: when we submit a task, we Catch all possible exceptions and handle them ourselves.

In other words, trycatch all the business logic. The disadvantages of this approach are: 1) All different task types require trycatch, which increases the amount of code. 2) Where there is no checkedexception, trycatch should also be used.

Thread pool implementation

The second approach avoids both of these problems.

The second way of thinking has the following four ways of implementation

Custom thread pools

Custom thread pool that inherits ThreadPoolExecutor and overwrites its afterExecute(Runnable r, Throwable T) method.

Realize Thread. UncaughtExceptionHandler interface

Realize Thread. UncaughtExceptionHandler interface, the realization of void uncaughtException (Throwable Thread t, e); Method and passes this handler to the ThreadFactory of the thread pool

Inheritance ThreadGroup

Override its uncaughtException method. (similar to the second option, because the ThreadGroup class itself to achieve the Thread. UncaughtExceptionHandler interface)

Note that the above three methods are used to submit the task through execute(xx). If you submit the task using submit(), the above three methods will not work and the following method should be used instead

Adopting the Future pattern

If the task is submitted using the Submit method, the method returns a Future object from which all exceptions and processing results can be retrieved. Using the Future pattern, return results and exceptions are put into the Future and processed in the Future

conclusion

Exception handling is a very important process in Java, but by default in the thread pool, it can be quietly ignored, which can be fatal in some cases.

The article explores various ways to transform the code from the user level to the thread pool level to make the business code more robust and controllable.