Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problems caused by asynchronous tasks

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "how to solve the problems caused by asynchronous tasks". In daily operation, I believe that many people have doubts about how to solve the problems caused by asynchronous tasks. I have consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to solve the problems caused by asynchronous tasks". Next, please follow the editor to study!

Preface

Let's briefly talk about this code, which is to use an asynchronous thread to execute a piece of business logic. The example code is as follows:

/ / pre-logic. Thread thread=new Thread (new Runnable () {@ Override public void run () {try {/ / Asynchronous thread executes other business logic} catch (Exception e) {/ / No code processing}); thread.start ()

Based on the experience of the old programmer, I guessed that an exception might have occurred in the asynchronous thread, which caused the asynchronous thread to exit and no longer continue execution. And because the above code "eats" the exception, it makes us look from the outside that the project is running and does not move, and there is nothing in the log.

So I modified it, printed out the relevant exception log, and finally located the problem. It turned out that there was a problem with the data made by Miss Sister, which led to the NPE problem.

"I don't know if you have ever encountered the above situation, using threads to execute the relevant logic asynchronously, but in the middle of execution, it is suddenly like the owner of the card and does not continue to execute. "

To sum up, it is divided into the following three situations:

Asynchronous tasks are blocked for a long time

An exception occurred in an asynchronous task

Asynchronous task exception is eaten

Asynchronous tasks are blocked for a long time

First, an asynchronous thread executes a task, which requires other remote services to be invoked over the network. Suppose the server responds very slowly, and the network timeout we set is very long, which will cause the thread to be blocked for a long time.

Suppose the pseudo code of an asynchronous task is as follows:

ThreadPoolExecutor threadPool=....; threadPool.execute (()-> {/ / 1. Call the remote service Socket socket....; / / 2. Set the timeout socket.setSoTimeout (60-1000); / / 3. The read server returns socket.read ();})

In the above program, if the server never returns, the asynchronous thread will be blocked until it times out.

This situation is actually good, we can only wait a period of time, we can see that the asynchronous thread continues to execute the task.

To take an extreme example, assuming that the above code does not set a timeout and the server never returns a response, "at this point the asynchronous thread will be blocked all the time."

In addition to the above example of network read blocking, there are common situations

Performed a long dormancy, such as TimeUnit.MINUTES.sleep (60)

There's a deadlock inside.

Wait

If asynchronous threads are blocked for a long time and asynchronous tasks are executed more frequently, the available threads in the thread pool will be slowly exhausted and subsequent tasks will be refused to execute.

Solution.

In fact, it is very simple. First, we use the jstack command "dump" to take a look at the thread stack of the current Java application, and then locate the relevant threads based on the thread pool name.

I randomly found the stack diagram on the Internet.

If you do not have a custom thread pool ThreadFactory parameter, it is troublesome to find and locate blocked threads.

Therefore, it is recommended to customize the ThreadFactory parameter to create a thread pool, which is very useful for troubleshooting problems later.

Asynchronous task exception not caught

In the above case, the asynchronous thread is actually alive, but blocked and unable to execute subsequent logic.

What about this kind of situation, which is different from the above, because an error occurs inside the asynchronous task and an exception is thrown, and there is no capture processing in the code logic, which causes the thread to exit abnormally in advance.

The abnormal exit pseudo code is as follows:

/ / 1. Create the executed task Runnable runnable=new Runnable () {@ Override public void run () {/ / execute the pre-logic / / throw the exception int iTunes 100Universe 0; / / execute the post-logic}}; / / 2. Create thread Thread thread=new Thread (runnable); / / 3. Run asynchronous thread thread.start (); / / other business logic

In the above code, the asynchronous thread executes the divisor logic, an exception will be thrown, and then the asynchronous thread will exit unexpectedly.

"exception logs thrown within an asynchronous thread are only printed to the console, not logged to the log file. "

So there is no thread exception log in the normal business log, which gives us the illusion that the asynchronous thread still seems to be executing the task, but in fact it is dead.

PS: the above words may be difficult to understand. For example, if you use IDEA to execute the above program, the exception log will be output to the console under IDEA.

If we execute this program on the Linux machine, the exception log will only be displayed on the current terminal window, and once the current terminal window is closed, the log will not be found. Yes.

If we want to save this kind of log, we need to redirect stdout to the log file, such as by executing the following command:

-- output stdout redirection to a file nohup java xxxx > $STDOUT_FILE 2 > & 1 &

Solution.

The first solution, which many readers have already thought of, is to catch all exceptions using try..catch statements in asynchronous threads.

"Yes, it's that simple. "

One point here, however, is that in general, we only catch Exception exceptions when we use try..catch.

In extreme cases, if Error is thrown in an asynchronous thread, for example, java.lang.NoClassDefFoundError is thrown, it cannot be captured at this time, and the asynchronous thread will still exit abnormally.

So we can use try..catch to capture Throwable, so that if an Error error occurs, it will also be caught.

However, I think it is enough to catch Exception exceptions, and Error errors rarely occur in normal engineering applications, so we just need to know that this is possible.

Ps: in the past, a colleague launched an application and used asynchronous threads to execute tasks. Each time they were halfway through execution, they stopped executing.

Because the Exception exception is handled by try..catch capture in the asynchronous thread, I don't know what the problem is after looking for it for a long time.

Finally, Brother Black inspected the stdout output log and found that an Error error occurred in the asynchronous thread.

This solution requires us to take the initiative to catch exceptions, and the second solution below is to set up thread exception handling.

Once the setting is complete, if an exception occurs within the asynchronous thread, the exception handling method will be called before the thread exits.

Let's take Thread as an example, and its setting method is as follows:

Runnable runnable=new Runnable () {@ Override public void run () {int iTunes 100 Throwable 0;}}; Thread thread=new Thread (runnable); thread.setUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler () {@ Override public void uncaughtException (Thread t, Throwable e) {System.out.println (t.getName () + "exception occurs" + e.getMessage ());}}); thread.start ()

However, it is not recommended to use Thread directly in the production environment, we need to use thread pools instead.

There are two ways to handle thread pool setting exceptions. If we use ThreadPoolExecutor#execute to perform asynchronous tasks, then we need to use the ThreadFactory setting when customizing the thread pool.

ThreadPoolExecutor threadPool = new ThreadPoolExecutor (5,10,60, TimeUnit.SECONDS,new ArrayBlockingQueue (100), / / Guava's ThreadFactoryBuilder class is used here It is convenient to construct ThreadFactory new ThreadFactoryBuilder () .setUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler () {@ Override public void uncaughtException (Thread t, Throwable e) {/ / handling exceptions}}) .build ()

If you currently use ThreadPoolExecutor#submit to perform asynchronous tasks, it's easy. We can get the exception thrown in the thread directly through Future#get.

Future future = threadPool.submit (new Callable () {@ Override public Object call () throws Exception {return "Blackie 11:30";}}); try {future.get ();} catch (InterruptedException e) {e.printStackTrace ();} catch (ExecutionException e) {/ / the exception thrown in the thread will be encapsulated in ExecutionException}

Asynchronous task exception is eaten

Well, finally to the last situation, this is the kind of situation that Brother Black encountered this time.

Specifically, all exceptions are caught within the asynchronous thread using the try..catch statement, but no code processing is performed in the catch statement.

Thread thread=new Thread (new Runnable () {@ Override public void run () {try {int iTunes 100AGOO;} catch (Exception e) {/ / No code processing}); thread.start ()

As shown in the above code, there is no code processing in the catch statement. Even if an exception does occur in an asynchronous thread, there will be no hint, and the exception is like being eaten.

At this point, the study on "how to solve the problems caused by asynchronous tasks" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report