1. Introduction
This article records some knowledge points about the interrupt mechanism in JAVA multi-threading. Mainly the differences between the stop method, interrupted() and isInterrupted() methods, and a simple analysis from the implementation of the source code.
There are 3 ways to terminate a running thread in JAVA
①The thread exits normally, that is, the run() method has been executed
②Use the stop() method in the Thread class to forcefully terminate the thread. But the stop() method has expired. It is not recommended to use
③Use the interrupt mechanism.
There is nothing wrong with the thread exiting normally. The interrupt mechanism is introduced in detail below. Let’s first look at the source code of the stop() method. The key is the source code. annotation. It explains why stop() is unsafe. 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()); }
The above comment, lines 9 to 16 indicate that the stop() method can stop "other threads". The thread that executes the statement of the thread.stop() method is called the current thread, and "other threads" are the threads represented by the object thread that calls the thread.stop() method.
For example:
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 the "other thread "thread". This other thread is the thread represented by the thread object of the new MyThread class.
Lines 21 to 23 indicate that you can stop a thread that has not yet been started (started ) thread. Its effect is: when the thread is started, it ends immediately.
The comments after line 48 clearly show why the stop() method is deprecated!
For example, the threadA thread has monitors, which are responsible for protecting certain critical resources, such as the amount of a bank transfer. When the transfer is in progress, the main thread calls the threadA.stop() method, resulting in the monitor being blocked. Release, the resources it protects (transfer amount) are likely to be inconsistent. For example, account A decreases by 100, but account B does not increase by 100
Second, the details of how to use the interrupt mechanism correctly in JAVA are too much. More. The interrupted() method and the isInterrupted() method both reflect whether the current thread is in an interrupted state.
①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); }
It can be seen from the comments in the source code that it tests the current thread.
②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); }
It can be seen from the source code comments that the isInterrupted() method will not clear the interrupt status
③interrupted() method and isInterrupted() method. The difference
It can be seen from the source code that both methods call isInterrupted(boolean ClearInterrupted), but one parameter is true and the other parameter 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);
So, the first difference. That is, one will clear the interrupt flag bit, and the other will not clear the interrupt flag bit.
After analyzing the source code, we can see that the second difference is in the return statement:
public static boolean interrupted() { return currentThread().isInterrupted(true); } /************************/ public boolean isInterrupted() { return isInterrupted(false); }
interrupted() tests the current thread. Interrupted status. And isInterrupted() tests the thread represented by the object that calls this method. One is a static method (it tests the interruption status of the current thread), and the other is an instance method (it tests the thread represented by the instance object).
The following uses a specific example to further clarify this difference.
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 + )); } } }
Look at the 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("是否停止?="+thread.interrupted());//false System.out.println("是否停止?="+thread.interrupted());//false main线程没有被中断!!! //......
No. 5 Line starts the thread thread, and line 6 sleeps the main thread for 1 second so that the thread thread has a chance to get CPU execution.
After the main thread sleeps for 1 second, 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 the main thread. Because:
(1) interrupted() tests the interruption status of the current thread
(2) The main thread executed the 9th line of statements, so the main thread is the current thread
Let’s look at the 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("是否停止?="+thread.isInterrupted());//true
In line 8, it is the isInterrupted() method called by the thread object. Therefore, what is tested is the interruption status of the thread represented by the thread object. Since in line 7, the main thread requests to interrupt the thread thread, the result in line 8 is: true
For more JAVA multi-thread interruption mechanism stop(), interrupted(), isInterrupted() related articles, please pay attention to PHP Chinese net!