Analysis on the proper stopping of Java threads and the correctness of Java threads

Source: Internet
Author: User
Tags deprecated

Analysis on the proper stopping of Java threads and the correctness of Java threads
Method for terminating thread errors: destroy and stop

I remember that when I was a beginner in Java, due to lack of knowledge about lock, synchronization, asynchronous, and other threads, I thought that both the destroy and stop methods can correctly stop Java thread execution. However, with the accumulation of work and some understanding of thread security, we gradually realized that these two methods are problematic, the two methods have long been named and discarded in java doc.

The destroy () method does not actually do anything, but throws a NoSuchMethodError. Therefore, the method cannot terminate the thread, so it cannot look at the text business:

/**     * Throws {@link NoSuchMethodError}.     *     * @deprecated This method was originally designed to destroy this     *     thread without any cleanup. Any monitors it held would have     *     remained locked. However, the method was never implemented.     *     If if were to be implemented, it would be deadlock-prone in     *     much the manner of {@link #suspend}. If the target thread held     *     a lock protecting a critical system resource when it was     *     destroyed, no thread could ever access this resource again.     *     If another thread ever attempted to lock this resource, deadlock     *     would result. Such deadlocks typically manifest themselves as     *     "frozen" processes. For more information, see     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">     *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.     * @throws NoSuchMethodError always     */    @Deprecated    public void destroy() {        throw new NoSuchMethodError();    }
The essence of the stop method is that it terminates the call of the run method directly and throws a ThreadDeath error because the thread is not secure. If the thread holds an object lock, the lock is released completely, resulting in inconsistent object statuses. For details, see the official java doc;
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 ThreadDeath 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 stop 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 interrupt method should be used to interrupt the wait. For more information, see <a target=_blank href="http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.

Correct thread termination

After the preceding destroy and stop methods are all negated, what other methods can be used to terminate threads correctly? In general, there are two solutions in java:

  • Mark, which ends with a flag in the run method. This method is not used as an example because it is common.
  • Interrupt, through exception interruption

Next we will discuss interrupt.

/**     * Interrupts this thread.     *     * <p> Unless the current thread is interrupting itself, which is     * always permitted, the {@link #checkAccess() checkAccess} method     * of this thread is invoked, which may cause a {@link     * SecurityException} to be thrown.     *     * <p> If this thread is blocked in an invocation of the {@link     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}     * class, or of the {@link #join()}, {@link #join(long)}, {@link     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},     * methods of this class, then its interrupt status will be cleared and it     * will receive an {@link InterruptedException}.     *     * <p> If this thread is blocked in an I/O operation upon an {@link     * java.nio.channels.InterruptibleChannel </code>interruptible     * channel<code>} then the channel will be closed, the thread's interrupt     * status will be set, and the thread will receive a {@link     * java.nio.channels.ClosedByInterruptException}.     *     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}     * then the thread's interrupt status will be set and it will return     * immediately from the selection operation, possibly with a non-zero     * value, just as if the selector's {@link     * java.nio.channels.Selector#wakeup wakeup} method were invoked.     *     * <p> If none of the previous conditions hold then this thread's interrupt     * status will be set. </p>     *     * <p> Interrupting a thread that is not alive need not have any effect.     *     * @throws  SecurityException     *          if the current thread cannot modify this thread     *     * @revised 6.0     * @spec JSR-51     */    public void interrupt() {        if (this != Thread.currentThread())            checkAccess();        synchronized (blockerLock) {            Interruptible b = blocker;            if (b != null) {                interrupt0();           // Just to set the interrupt flag                b.interrupt(this);                return;            }        }        interrupt0();    }
According to the comments of the interrupt method and the implementation of the method body extracted from the java source code, it can be summarized as: by calling the interrupt method, a thread in the blocking state can throw an exception, that is, the interrupt method can be used to interrupt a thread in the blocking state. In addition, the method also sets the thread interruption state (Note: isInterrupted () can be used to query the interruption State ).

Practice test whether interrupt can interrupt a thread in the non-blocking state

Code:

Public class ThreadTest {/*** @ param args */public static void main (String [] args) {WorkThread wThread = new WorkThread (); wThread. start (); System. out. println ("start to call wThread. interrupt () "); wThread. interrupt (); System. out. println ("End wThread call. interrupt () ") ;}} class WorkThread extends Thread {public void run () {for (int I = 0; I <Byte. MAX_VALUE;) {System. out. println ("worker thread running" + (++ I ));}}}
Running result:


It is actually printed to the end of 127, because it is too long, only part is intercepted. We can find that the for loop runs until the value of variable I exceeds Byte. MAX_VALUE.

Conclusion: interrupt cannot interrupt non-blocking threads.

However, I can change my mind. Since the interrupt method was mentioned before will set the thread interruption status, I can use isInterrupt () to judge and interrupt the thread. (In essence, this scheme indicates interruption)

Code on, only add a flag to judge the condition loop of WorkThread -- isInterrupt ():

Class WorkThread extends Thread {public void run () {for (int I = 0; I <Byte. MAX_VALUE & isInterrupted ();) {System. out. println ("worker thread running" + (++ I ));}}}
Running result:


As a result, interrupt and isInterrupt () can interrupt non-blocking threads. Note: The essence is still a mark of interruption.

Can interrupt the blocked thread?

Code:

Public class ThreadTest {/*** @ param args */public static void main (String [] args) {WorkThread wThread = new WorkThread (); wThread. start (); System. out. println ("start to call wThread. interrupt () "); wThread. interrupt (); System. out. println ("End wThread call. interrupt () ") ;}} class WorkThread extends Thread {public void run () {System. out. println ("worker thread sleep"); for (int I = 0; I <Byte. MAX_VALUE;) {try {sleep (10*1000); System. out. println ("worker thread running" + (++ I);} catch (InterruptedException e) {System. out. println ("working thread InterruptedException"); break ;}} System. out. println ("the worker thread has finished running ");}}
Running result:

From the program to the running result, when the working thread enters sleep (that is, blocking), calling the interrupt method will prompt the thread to throw an exception.

Conclusion: interrupt can interrupt the thread in the blocking state.

Summary

Java does not have a mechanism to terminate the Thread immediately. The destroy and stop methods provided by the Java Thread class cannot terminate the Thread correctly. They can only be done through the flag or interrup method.

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.