Java concurrency framework-Support for AQS interruption

Source: Internet
Author: User

Java concurrency framework-Support for AQS interruption

The definition of threads provides us with a way to execute multiple tasks concurrently. In most cases, we end each task by itself, which ensures transaction consistency, but sometimes we want to cancel the task during task execution to stop the thread. In java, it is not easy to stop threads securely, quickly, and reliably. java does not provide any reliable methods to terminate thread execution. Back to section 6, there are two concepts in the thread scheduling policy: preemptible and collaborative. In the same way, there are also collaborative and preemptible interrupt mechanisms.

In history, Java once used the stop () method to terminate the running of threads. They are preemptible interruptions. However, it has caused many problems and has long been deprecated by JDK. Calling the stop () method means ① all the locks held by the thread will be released, and the release of the locks is uncontrollable. ② The ThreadDeath exception will be thrown immediately, no matter where the program runs, but it is not always valid. If there is lock competition for terminated threads, the first point will lead to data consistency problems, which is easy to understand, generally, data locks are used to protect data consistency, and the thread stops releasing the lock, which may result in inconsistent presentation of the protected data and eventually cause errors in program operations. The second point is vague. The problem to be explained is that the stop () method may not terminate the thread in time or even cannot terminate the thread. Check what will happen in the following code. It seems that the thread mt will stop because the stop () method is executed. It is reasonable to say that even if the execut method is an endless loop, as long as the stop () method is executed () the method thread ends and the infinite loop ends. Otherwise, because we used synchronized modification in the execute method, the synchronization method indicates that the mt object will be locked when execute is executed. In addition, the stop () method of Thread is also synchronized, therefore, the mt object lock must be obtained before calling the stop () method of the mt thread, but the mt object lock is occupied by the execute method and not released, so stop () the method can never obtain the mt object lock. Finally, we can draw a conclusion that the stop () method is not reliable, and it may not always be effective to terminate the thread.

Public class ThreadStop {

Public static voidmain (String [] args ){

Thread mt = new MyThread ();

Mt. start ();

Try {

Thread. currentThread (). sleep (100 );

} Catch (InterruptedException e ){

E. printStackTrace ();

}

Mt. stop ();

}

Static classMyThread extends Thread {

Publicvoid run (){

Execute ();

}

Privatesynchronized void execute (){

While (true ){

}

}

}

}

After a long period of development, Java finally chooses to use a collaborative interrupt mechanism to implement interruption. The principle of collaborative interrupt is very simple. Its core is to mark the interrupt mark first. A thread sets the interrupt mark bit of a thread, the thread marked with the interrupt bit will throw an exception at the appropriate time node, and handle the exception after capturing the exception. There are three main points to consider for implementing collaborative interruptions: ① is to implement polling interrupt identifiers at the Java level or in JVM; ② is to control polling granularity, generally, the granularity should be as small as possible and the cycle should be as short as possible to ensure the timeliness of the response; ③ the selection of polling time nodes is actually in which method the polling is, for example, the JVM will Thread-class wait (), sleep (), join (), and other methods all implement polling of the interrupt identifier.

Where are the interrupt identifiers? Interruption is intended for thread instances. From the Java perspective, it is no longer appropriate to put the identifier variable into the thread. However, the interrupt identifier is maintained by the local method because it is maintained by the JVM. At the Java layer, only a few APIs are left for the Operation interruption identifier, as shown below,

Public class Thread {

Public voidinterrupt (){......}

Public BooleanisInterrupted (){......}

Public static Booleaninterrupted (){......}

}

The preceding three methods are used to set the thread to the interrupted state, determine whether the thread state is interrupted, clear the current thread interruption state, and return the previous value. The interrupt () method is used to set the interrupt identifier. If the non-blocking thread only changes the interrupt status, the thread will continue to run, but if the thread can cancel the blocking, for example, threads that are executing methods such as sleep (), wait (), and join () throw an InterruptedException exception because the thread is set to interrupt. The program captures and processes this exception.

The first of the three points mentioned above is the implementation of polling at which layer, which has no special requirements. In reality, as long as there is no logical problem, it can be implemented at the Java or JVM level. For example, common operations such as thread sleep and waiting are implemented through JVM, while the interruption in the AQS framework is implemented in Java, at any level, the round robin process must ensure that no blocking occurs. The second is to ensure that the granularity of polling is as small as possible and the cycle is as short as possible, which is related to the speed of interrupt response. The third point is about the selection of polling time nodes.

For the three key points, let's take a look at how the AQS framework supports the interruption, mainly waiting for the process of obtaining the lock to provide the interruption operation. below is the pseudocode. You only need to add red and bold logic to implement interrupt support. In the loop body, the current thread interrupt identification bit is judged for each loop. Once the thread is marked as interrupted, an InterruptedException exception is thrown, the high-level code completes the interrupt processing by capturing and processing this exception. In summary, the ASQ framework implements the mechanism for getting locks at the Java level. The round-robin time nodes choose to keep trying to get locks, and each cycle has a small granularity, the response speed is guaranteed, and there is no blocking risk in the loop process, so that the interrupt detection will not fail.

If (failed to get the lock ){

Create a node

Use CAS to insert a node to the end of the queue

While (true ){

If (the attempt to obtain the lock is successful and the node's precursor node is the header node ){

Set the current node as the header Node

Skip Loop

} Else {

Use CAS to change the waitStatus ID of the node precursor node to signal

If (modified successfully ){

Suspend current thread

If (the current thread interrupt bit is identified as true)

An InterruptedException exception is thrown.

}

}

}

It is actually very easy to judge whether a Thread is in the interrupted state. You only need to use the Thread. interrupted () operation. If it is true, it indicates that the Thread is in the interrupt bit and the interrupt bit is cleared. So far, AQS supports the interrupted lock acquisition operation.

This section analyzes the preemptible and collaborative interruptions from the java development process. Because of some defects in preemptible interruptions, it is not recommended to use them now, and collaborative interruptions are recommended, although the response time is long, however, it has unparalleled advantages. Collaborative interruption can be implemented at the JVM level, or at the Java level. For example, the interruption of the AQS framework is implemented at the Java level, however, if we continue to study it Because Java has left several APIs for the interrupt identification space of our operation thread, this enables the implementation of the interrupt operation at the Java level. Some people are certain to criticize java's collaborative interrupt mechanism. Critics say that java does not have a preemptive interrupt mechanism, and the collaborative interrupt mechanism forces developers to maintain the interruption status and forces developers to process InterruptedException. However, those who are certain believe that, although the collaborative interrupt mechanism delays the handling of Interrupt requests, it provides developers with more flexible interrupt handling policies and may be less responsive than preemptive ones, but the program is more robust.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.