JAVA multithreaded interrupt mechanisms stop of interrupted of isInterrupted of

  • 2020-05-09 18:43:01
  • OfStack

1,

This article documents some knowledge of the interrupt mechanism in JAVA multithreading. Mainly is the stop method, interrupted() and isInterrupted() method difference, and from the source code implementation on the simple analysis.

There are three ways to terminate a running thread in JAVA

The thread exits normally, that is, the run() method is finished

Use the stop() method in Thread class to terminate the thread. However, the stop() method has expired and is not recommended

Use the interrupt mechanism

Thread normal exit without what east east, interrupt mechanism is described in detail below, first look at the stop() method source code, the key is the source code on the comments. It explains why stop() is not secure, which thread does the stop() method stop?


/**
* Forces the thread to stop executing.
* <p>
* If there is a security manager installed, its <code>checkAccess</code>
* method is called with <code>this</code>
* as its argument. This may result in a
* <code>SecurityException</code> being raised (in the current thread).
* <p>
* If this thread is different from the current thread (that is, the current
* thread is trying to stop a thread other than itself), the
* security manager's <code>checkPermission</code> method (with a
* <code>RuntimePermission("stopThread")</code> argument) is called in
* addition.
* Again, this may result in throwing a
* <code>SecurityException</code> (in the current thread).
* <p>
* The thread represented by this thread is forced to stop whatever
* it is doing abnormally and to throw a newly created
* <code>ThreadDeath</code> object as an exception.
* <p>
* It is permitted to stop a thread that has not yet been started.
* If the thread is eventually started, it immediately terminates.
* <p>
* An application should not normally try to catch
* <code>ThreadDeath</code> unless it must do some extraordinary
* cleanup operation (note that the throwing of
* <code>ThreadDeath</code> causes <code>finally</code> clauses of
* <code>try</code> statements to be executed before the thread
* officially dies). If a <code>catch</code> clause catches a
* <code>ThreadDeath</code> object, it is important to rethrow the
* object so that the thread actually dies.
* <p>
* The top-level error handler that reacts to otherwise uncaught
* exceptions does not print out a message or otherwise notify the
* application if the uncaught exception is an instance of
* <code>ThreadDeath</code>.
*
* @exception SecurityException if the current thread cannot
* modify this thread.
* @see #interrupt()
* @see #checkAccess()
* @see #run()
* @see #start()
* @see ThreadDeath
* @see ThreadGroup#uncaughtException(Thread,Throwable)
* @see SecurityManager#checkAccess(Thread)
* @see SecurityManager#checkPermission
* @deprecated This method is inherently unsafe. Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
* any of the objects previously protected by these monitors were in
* an inconsistent state, the damaged objects become visible to
* other threads, potentially resulting in arbitrary behavior. Many
* uses of <code>stop</code> should be replaced by code that simply
* modifies some variable to indicate that the target thread should
* stop running. The target thread should check this variable
* regularly, and return from its run method in an orderly fashion
* if the variable indicates that it is to stop running. If the
* target thread waits for long periods (on a condition variable,
* for example), the <code>interrupt</code> method should be used to
* interrupt the wait.
* For more information, see
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated
public final void stop() {
stop(new ThreadDeath());
}

Lines 9 through 16 of the above comment indicate that the stop() method can stop "other threads." The thread that executes the thread.stop () method is called the current thread, and the "other threads" are the threads represented by thread, the object that calls the thread.stop () method.

Such as:


public static void main(String[] args) {
MyThread thread = new MyThread...
//.....
thread.stop();
//....
}

In the main method, the current thread is the main thread. It executes to line 4 and wants to stop "other threads" thread. This other thread is the thread represented by the thread object of new class MyThread.

Lines 21 through 23 indicate that you can stop a thread that has not already been started by started. It works like this: when the thread starts, it ends immediately.

The comment after line 48 is a good example of why the stop() method was abandoned! Why it's not safe.

For example, the threadA thread has monitors that protect certain critical resources, such as the amount of money transferred by a bank. While the transfer is in progress, the main thread calls the threadA.stop () method. As a result, the monitor is released and the resource it protects (the transfer amount) is likely to be inconsistent. For example, the A account dropped by 100, while the B account did not increase by 100

2. Interrupt mechanism

There are too many details in JAVA about how to use the interrupt mechanism correctly. Both the interrupted() and isInterrupted() methods reflect whether the current thread is in an interrupted state.

1) interrupted ()


/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
* other words, if this method were to be called twice in succession, the
* second call would return false (unless the current thread were
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if the current thread has been interrupted;
* <code>false</code> otherwise.
* @see #isInterrupted()
* @revised .
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}

As you can see from the comments to the source code, it tests the interrupt state of the current thread (current thread), and this method clears the interrupt state.

(2) isInterrupted ()


/**
* Tests whether this thread has been interrupted. The <i>interrupted
* status</i> of the thread is unaffected by this method.
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if this thread has been interrupted;
* <code>false</code> otherwise.
* @see #interrupted()
* @revised .
*/
public boolean isInterrupted() {
return isInterrupted(false);
}

As you can see from the source code comments, the isInterrupted() method does not clear the interrupted state.

The difference between the interrupted() method and the isInterrupted() method

As you can see from the source code, both of these methods are called isInterrupted(boolean ClearInterrupted), except that one of the arguments is true and the other is false.


/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);

Therefore, the first difference is that one will clear the interrupt identifier bit and the other will not clear the interrupt identifier bit.

Analyzing the source code again, we can see the second difference in the return statement:


public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/************************/
public boolean isInterrupted() {
return isInterrupted(false);
}

interrupted() tests the interrupt state of the current thread. isInterrupted(), on the other hand, tests the thread represented by the object calling the method. One is a static method (which tests the interrupted state of the current thread) and one is an instance method (which tests the interrupted state of the thread represented by the instance object).

Let's take this distinction one step further with a concrete example.

There is a custom thread class as follows:


public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = ; i < ; i++) {
System.out.println("i=" + (i + ));
}
}
}

Let's start with an example of the interrupted() method:


public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep();
thread.interrupt();
//Thread.currentThread().interrupt();
System.out.println(" Do you want to stop? ="+thread.interrupted());//false
System.out.println(" Do you want to stop? ="+thread.interrupted());//false main The thread is not interrupted !!!
      //......

Line 5 starts the thread thread, and line 6 puts the main thread to sleep for 1 second so that the thread thread has a chance to get an CPU execution.

After the main thread sleeps 1s clock, it resumes execution to line 7 and requests to interrupt the thread thread.

Line 9 tests whether the thread is in an interrupted state, which thread is being tested here?? The answer is main threads. Because:

(1) interrupted() tests the interrupt state of the current thread

(2) the main thread executes line 9, so the main thread is the current thread

Let's look at an example of the isInterrupted() method:


public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep();
thread.interrupt();
System.out.println(" Do you want to stop? ="+thread.isInterrupted());//true

In line 8, is the isInterrupted() method called by the thread object. Therefore, the interrupt state of the thread represented by the thread object is tested. Because at line 7, the main thread requests to interrupt the thread thread, the result at line 8 is: true


Related articles: