It turns out that this is the thread closing method recommended by JDK

This is a community that may be useful to you

One-to-one communication/interview brochure/resume optimization/job search questions, welcome to join the “Yudao Rapid Development Platform” Knowledge Planet. The following is some information provided by Planet:

  • “Project Practice (Video)”: Learn from books, “practice” from past events

  • “Internet High Frequency Interview Questions”: Studying with your resume, spring blossoms

  • “Architecture x System Design”: Overcoming difficulties and mastering high-frequency interview scenario questions

  • “Advancing Java Learning Guide”: systematic learning, the mainstream technology stack of the Internet

  • “Must-read Java Source Code Column”: Know what it is and why it is so

1afbab814a4fb256261680561be082a9.gif

This is an open source project that may be useful to you

Domestic Star is a 100,000+ open source project. The front-end includes management backend + WeChat applet, and the back-end supports monomer and microservice architecture.

Functions cover RBAC permissions, SaaS multi-tenancy, data permissions, mall, payment, workflow, large-screen reports, WeChat public account, etc.:

  • Boot address: https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud address: https://gitee.com/zhijiantianya/yudao-cloud

  • Video tutorial: https://doc.iocoder.cn

Source: juejin.cn/post/
7291564831710445622

  • 1 Common scenarios that require thread exit

  • 2 Graceful shutdown or forced shutdown

  • 3 Ways to exit threads in other languages and Java language

  • 4 Exit the thread gracefully

  • 5 Summary

4ad5b1aa2570887f240df880d5f3f8b4.jpeg

JDK clearly cannot forcibly destroy a thread in the thread’s Stop method, but must exit the thread gracefully.

What is meant by gracefully exiting a thread, that is, in-progress requests are correctly processed, pending requests are canceled, resource recycling is performed, and finally the Thread Runable run method return ends execution.

First ask why you want to exit a thread, and then ask how to exit a thread

1 Common scenarios that require thread exit

  • The task execution is completed or terminates abnormally, and the task considers that it no longer needs to occupy the thread.

  • The thread pool scales the thread pool according to the current task execution status. When there are fewer tasks to perform, exit the idle thread.

  • During the shutdown phase of a service or process, such as rolling release, it is necessary to exit the thread, close the thread pool, and close the process.

  • When scheduled tasks and periodic tasks need to be terminated, the current thread needs to be exited. Or exit the execution of the current task.

In short, since you can create a thread, you will have the ability to exit a thread. There will also be scenarios where the thread exits.

There are two types of ways to close a thread: informing the thread to actively close and forcibly closing and destroying the thread.

Backend management system + user applet implemented based on Spring Boot + MyBatis Plus + Vue & Element, supporting RBAC dynamic permissions, multi-tenancy, data permissions, workflow, three-party login, payment, SMS, mall and other functions

  • Project address: https://github.com/YunaiV/ruoyi-vue-pro

  • Video tutorial: https://doc.iocoder.cn/video/

2 Graceful shutdown or forced shutdown

dd66a662bd99be55c5bdcffde6435cf4.png

In fact, forcibly closing a thread has many disadvantages. If the thread is suddenly closed before the distributed lock is released, then the distributed lock cannot be released. As a result, subsequent normal lock requests fail and are blocked, affecting user bills of lading, etc. Forcibly closing a thread is tantamount to directly powering off the server.

Backend management system + user applet implemented based on Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element, supporting RBAC dynamic permissions, multi-tenancy, data permissions, workflow, three-party login, payment, SMS, mall and other functions

  • Project address: https://github.com/YunaiV/yudao-cloud

  • Video tutorial: https://doc.iocoder.cn/video/

3 Ways to exit threads in other languages and Java language

How to exit a thread in languages other than Java? In fact, every implementation has one. For example, in C++, thread execution can be forcibly terminated through ExitThread and TerminateThread. Linux not only provides the pthread_exit C language system call to forcefully close the thread, but also provides graceful exit methods such as pthread_cancel to notify the thread to close.

Java also provides two exit methods: graceful and forced exit. However, it is clearly not recommended in the JDK to force the thread to be interrupted. In the comments of Thread.stop() to force the thread to be interrupted, the JDK explains this

Thread.stop() This method itself is unsafe. Stopping a thread will unlock the monitor (can be understood as a lock) held by this thread. If these monitors (locks) are blocked, ) protected critical objects are in an inconsistent state, other threads may see that these objects are in an inconsistent state, which will lead to unknown behavior. Calls to Thread.Stop() should be replaced by simple code, such as modifying a variable, checking the variable periodically by the target thread, and returning from the run method in an orderly manner. If the target thread waits on a condition variable, other threads should interrupt the target thread using the interrupt method.

In fact, closing a thread forcefully and notifying are two different concepts, that is, whether the developer of the thread task should be trusted to actively exit the thread gracefully and quickly instead of being forcibly terminated by other threads. In Java, there is only one recommended way to exit a thread, which is to exit gracefully, and the JDK also gives suggestions. By modifying variables, the target thread periodically checks the status. Or notify the target thread through interrupt.

Let’s discuss how to exit a thread gracefully?

4 Exit the thread gracefully

What are the ways?

Business field tag

Business systems often encounter requests to terminate a task. For example, there are scheduled tasks in the system. For example, after the takeout coupon package expires, the unused amount will be automatically refunded to the user. Assume that while the task is being executed, I need to redefine the input parameters of the task and terminate the task first. How to do it?

Most task codes will be processed in a loop, such as scanning the entire table to execute certain business logic. There must be a loop processing scenario, and we can determine whether the task needs to be terminated at the loop entrance. In this way, by controlling this field, we can terminate the task execution.

During specific implementation, you can control whether a certain task should be terminated through the configuration center.

while(config.isTaskEnable()) {
    //Get whether the task should be terminated from the configuration center
    //Loop to execute business logic. Exit until execution completes, or is terminated.
}

This exit method tells the thread “you should exit at the appropriate time”, and the thread itself chooses to check the status at the appropriate time. Then when developers design task codes, they must design reasonable exit points in advance and check whether they need to exit at the exit point.

Thread.interrupt()

The JDK mentions that if the target thread is not in the running state, but in the blocked state, it is naturally impossible to check the exit status mark. How to notify this thread to exit?

JDK: If the target thread waits on a condition variable, other threads should interrupt the target thread using the interrupt method.

The JDK comment for interrupt mentions,

If another thread calls the interrupt method of the target thread,

  • It happens that the target thread is calling. When using Object.wait(), object.join (), Object.sleep(), etc., the interrupt bit mark of the target thread is cleared. , and the target thread will immediately resume from sleep, wait, etc. calls, and be thrown InterruptException.

  • If the target thread is blocked during an IO operation, such as io.channels.InterruptibleChannel, the Channel will be closed, the thread’s interrupt bit is set, and the target thread receives java.nio.channels. ClosedByInterruptException.

  • If the target thread is blocked on java.nio.channels.Selector, the thread interrupt status is set, and then the target thread immediately returns a non-zero value from select.

  • If all other conditions are not true, the thread interrupt bit will be set.

The thread interrupt bit marks whether the current thread is in an interrupted state, and the Thread.isInterrupted method is provided to check whether the current thread is in the interrupted bit? Then why does the target thread throw an interruptException and cancel the mark when it is blocked in the Object.wait(), Sleep() method? In fact, the interrupt operation performs two things, 1) setting the interrupt bit mark 2) waking up the target thread through unpark (park and unpark can block the thread and wake up the thread respectively).

However, when the target thread wakes up, it will check whether it is currently in the interrupt bit, if it is a sleep or wait operation. If it is in the interrupt bit, cancel the interrupt bit and throw an exception. The reason for canceling the middle segment should be a specification, that is, throwing an interrupt exception means that the thread is notified of the interruption, and there is no need to use the middle segment mark.

In other scenarios 2 and 3, after being awakened, the corresponding interrupt response strategies are executed respectively.

The interrupt interrupt logic is deterministic. The business thread must consider whether it has called sleep, wait or io, selector and other operations, and choose its own appropriate interrupt response strategy according to different scenarios.

So how does the recommended business thread respond to interrupts?

Recommended interrupt response strategies

Respond to interruption immediately

  • When the target thread’s task is in InterruptedException exception handling, it must actively recycle resources, print logs, and exit task execution.

  • If the target thread has no blocking operations, such as sleep and wait. You can check the current interrupt bit status through Thread.isInterrupted(). If it is interrupted, take the first step above.

Ignore the interruption and leave it to the upper layer for processing

The so-called upper layer can be understood as the upper layer of the call stack. For example, the code in this layer is not responsible for handling the interrupt scenario. Then after the Interrupt exception is thrown, you can choose a solution:

  • Throw InterruptedException to the upper layer, which will be handled by the upper layer code.

  • Call Thread.interrupt(). Reset the interrupt bit flag (interrupt yourself). After the method of this layer returns, the upstream code checks the interrupt bit mark and performs interrupt processing.

Of course, the most recommended way is to throw InterruptedException, so that the upstream can perceive that there is a blockage in the downstream call chain and let the upstream process the interrupt exception.

Never swallow interrupts

What is swallowing interrupts? For example, when sleep throws InterruptedException, it ignores the exception, does not perform any operations, and continues to execute business logic.

for (int i = 0; i < cnt; i + + ) {
   try {
      //Execute business logic
      Thread.sleep(10000);
   } catch (InterruptedException e) {

      System.out.println("Interrupted");
   }
   System.out.println("Child thread is executing");
}

If handled in this way, the interrupt exception is ignored and the interrupt flag bit is also ignored. Even if the upstream method has a handling strategy for interrupts, it cannot sense the interrupt. For example, upstream calls may determine.

while(true){
    callChildMethod(); //Call the downstream method, but the downstream swallowed the interrupt
    if (Thread.currentThread().isInterrupted()) {
       //Recycle resources and exit the thread
    }
}

Some people may ask, since the upper layer can know how to handle interrupts, why don’t the developers of lower layer methods remember to throw interrupts or reset the interrupt bit?

Because there are two levels, it is probably not a developer. For example, the upper layer is a general framework code, which defines the specified logic of the task and provides extension point methods. The downstream only needs to implement extension methods. However, another developer swallowed the interrupt exception when implementing the extension point method. As a result, the framework layer had already processed the interrupt, but still could not respond to the interrupt.

Therefore, interrupt response requires upper and lower layers, and each layer of code logic needs to be considered. Even if the framework layer handles interrupt exception handling, the business logic layer must also pay attention to interrupt handling.

As a final reminder, the Thread.interrupted method will return the current interrupt flag and cancel the interrupt bit. If you only query the interrupt bit and do not want to clean it up, you can use Thread.isInterrupted().

5 Summary

  • It is not recommended to forcefully destroy threads, which will result in resources not being released, in-progress requests not being processed normally, and business data being in an unknown state.

  • Java recommends exiting threads gracefully.

  • The business layer can use field tags to periodically check whether the task needs to be exited.

  • Thread.interrupt interrupts the target thread, isInterrupted queries the interrupt bit mark.

  • Using Thread.interrupt to handle interrupts can also exit gracefully, but both the upper and lower stacks need to pay attention to the interrupt and must not swallow the interrupt.

Welcome to join my knowledge planet and comprehensively improve your technical capabilities.

To join, Long press” or “Scan” the QR code below:

9f701c192b2b8289a20c4b5543fb04be.png

Planet’s content includes: project practice, interviews and recruitment, source code analysis, and learning routes.

26cddbe2ad5e9bfc3d45e81e0e1d511f.png

7ac4ee5bae5618181358017 a.png 409e439c97c18f993f61ac80816dc230.png 5e7ac6f4700096fd38293ce941503f52.png6fb6a2cbd377ab81 89e356d2165e74ef.png

If the article is helpful, please read it and forward it.
Thank you for your support (*^__^*)

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139421 people are learning the system