How to stop a running Java thread

Source: Internet
Author: User
Tags deprecated volatile

The content related to this issue mainly involves three parts: Obsolete thread.stop (), confusing Thread.Interrupt series, best practices shared Variable.

Obsolete Thread.stop ()
@Deprecatedvoid Stop () {    Stop (new Threaddeath ());} 

As the code for Java.lang.Thread.stop () in Hotspot JDK 7, learn about its doc:

This method is inherently unsafe. Use thread.stop () to stop a thread, resulting in the release (unlocking) of all monitors that the thread has locked (unlocked due to unchecked exception Threaddeath that propagate upward along the stack). If any objects previously protected by these monitors are in an inconsistent state, the inconsistent state of the object (the corrupted object) is visible to other threads, which can result in arbitrary behavior.

is not nearly the passage around the dizzy, vulgar point: The target thread may hold a monitor, assuming that the monitor controls the logical relationship between a certain two values, such as var1 must be less than var2, a moment var1 equals var2, should be protected by the logical relationship, Unfortunately, at this point, you receive a stop command that generates a Threaddeath error and the monitor is unlocked. This leads to logic errors, and of course this may not happen and is unpredictable. Note: Threaddeath is sacred? It's a java.lang.Error, not a java.lang.Exception.

Long Serialversionuid =-4417128565033088268L;}

Many applications of the Thread.stop () method should be replaced by code that "modifies only certain variables to indicate that the target thread should stop." The target line thread executes periodically checks the variable and exits the run method when it is found to indicate that it is going to stop. If the target thread waits for a long time, the wait should be interrupted using the interrupt method.

In fact, the best way to stop a thread is already implied here: Conditional variable or condition variable + interrupt.

For more information, see:
Why is Thread.stop, Thread.Suspend and Thread.Resume Deprecated?

Please refer to my translation xxx above.

Other doc about the Stop method:

  1. The method forces a thread to stop and throws a newly created Threaddeath object as an exception.
  2. Stopping a thread that has not yet started is allowed, and it terminates immediately if the thread is started later.
  3. Typically, you should not attempt to capture threaddeath unless it must perform some of the exception cleanup operations. If a catch clause captures a Threaddeath object, the object must be re-thrown so that the thread does not actually terminate.

Summary:
Thread.stop () is unsafe and is no longer recommended for use.

Confusing Thread.Interrupt ()

There are three methods in the thread class that will confuse the novice:

No return value//return value    //static, return value 

If according to the recent years popular reconstruction, the code neat Way, the programmer practice the way and so on the view of the book, these methods of naming relative to its realization function, is not straightforward, very easy confusing, is the low-level program ape code. Analyze individually:

void Interrupt () {    if (this!= Thread.CurrentThread ())        checkAccess ();    synchronized (blockerlock) {        interruptible b = blocker;        //Just to set the interrupt flag b.interrupt (return;}} interrupt0 ();    

Interrupts this thread. no return value. The specific role of the following several situations:

    • If the line is impersonating is blocked by the wait (),Wait (long),wait (long, int) method of the Object class, or the thread class's join (),join (Long),join (long, int),Sleep (long),sleep (long, int) method, The interrupt state of the thread is cleared and a java.lang.InterruptedExceptionis received.
    • If the line is impersonating blocks the I/O operation on the interruptible Channel, the channel is closed, the interrupt state of the thread is set, and a Java.nio.channels.ClosedByInterruptException.
    • If the line is impersonating is blocked by a java.nio.channels.Selector operation, the interrupt state of the thread is set, it is returned immediately from the selection operation, and may have a value other than 0, as if invoking the Java.nio.channels.Selector.wakeup () method.
    • If none of the above conditions are true, then the interrupt state of the thread will be set.

Summary: The first case is the most special, blocking the wait/join/sleep thread, the interrupt state will be cleared off, while receiving the famous interruptedexception, while the rest of the condition is set, and not necessarily receive an exception.

Breaking a thread that is not active does not have any effect. If the thread is interrupted by another thread, the Java.lang.Thread.checkAccess () method is called, which may throw java.lang.SecurityException.

Boolean interrupted () {    return CurrentThread (). isinterrupted (true); 

Detects whether the current thread has been interrupted, returns true, otherwise false, and clears the interrupt state. In other words, if the method is called consecutively two times, the second time will return false unless the first and second instantaneous thread is interrupted again. Returns False if the thread is no longer active when the call is interrupted.

Boolean isinterrupted () {    return isinterrupted (false);} 

Returns true if the current thread has been interrupted, or false. The interrupt state is not affected by this method. Returns False if the thread is no longer active when the call is interrupted.

The only difference between interrupted () and isinterrupted () is that the former reads and clears the interrupt state, which reads only the state.

In the hotspot source code, both are implemented by calling the native Method Isinterrupted (Boolean), which differs from the parameter value clearinterrupted.

Boolean isinterrupted (boolean clearinterrupted);

Through the above analysis, the difference between the three is very clear, to see a specific case, I saw in the work of an architect's code, just give the simplest outline structure:

void Run () {while  (! Thread.CurrentThread (). isinterrupted ()) {      try {           thread.sleep (10000L);           Break ;} }}

I was originally the code directly around the halo, with the thread.isinterrupted () method as a cyclic abort condition can it?

According to the above analysis, when the method blocks to Wait/join/sleep, the interrupt state is cleared and the interruptedexception is received, that is, the received value is false. In the code above, when the call Otherdomain.xxx () after sleep, the code in OtherDomain contains Wait/join/sleep and the interruptedexception is caught, the thread cannot be properly interrupted.

Therefore, when writing multithreaded code, it is the safest practice to capture interruptedexception at any time, either to continue to throw or reset the interrupt state, referring to "Java Concurrency in Practice". There is no absolute, if you can make sure that this is not the case, this code is also possible.

The next paragraph is quoted as follows: "Java Concurrent Programming Combat" 5th Chapter 5.4 Blocking method and interrupt method of foundation building module p77

When a method throws a interruptedexception, it indicates that the method is a blocking method. When calling a method in your code that will throw a interruptedexception exception, your own method becomes a blocking method and must handle the corresponding interrupt. For library code, there are two options:

    • Pass interruptedexception. This is the most sensible strategy to pass an exception to the caller of the method.
    • Resume interrupts. In cases where it cannot be thrown, such as the Runnable method, you must capture interruptedexception and restore the interrupt state through the interrupt () method of the current thread, so that the higher-level code in the call stack will see an interrupt thrown. The following code is a template:
void Run () {    try {          //① call block method        catch (interruptedexception e) {            thread.currentthread (). Interrupt ();    //② resuming the interrupted state}}   

Finally, again, ② Thread.CurrentThread (). Interrupt () is very, very important.

Best Practice: Shared Variable

I do not remember which book has been said, best practice is a rotten word. Here the word is most expressive, and the best way to stop a thread is to take advantage of shared conditional variables.

For this question, I think it's accurate to say that the best way to stop a thread is to have it done, and there's no way to stop a thread immediately, but you can control when or under what conditions let him finish.

By controlling the execution of a thread through a conditional variable, the thread checks the state of the variable and externally alters the value of the variable to control stop execution. To ensure instant communication between threads, it is necessary to use the volatile keyword or lock to ensure that the read thread is consistent with the state of the variable between the write threads. Here's a best template:

/** * @author Bruce_sha (bruce-sha.github.io) *  @version 2013-12-23 */< span class= "keyword" >public class bestpractice extends thread {private volatile span class= "keyword" >boolean finished = false; //①volatile condition variable public void stopme () {finished = span class= "keyword" >true; //② signaling stop Signal}  @Override public void run () { while (!finished) {//③ detection condition variable //do dirty work//④ business Code}}}                 

Please be patient while this article is not complete.

When the code at ④ is blocked by wait () or sleep (), the thread cannot immediately detect the condition variable. So the code at ② is best to call the interrupt () method at the same time.

Summary:
How to Stop a Thread or a Task? Discusses in detail how to stop a thread, summed up with three points:

    1. Use the violate Boolean variable to identify whether the thread is stopped.
    2. When you stop a thread, you need to call the stop thread's interrupt () method, because the thread may be in wait () or sleep (), increasing the immediacy of the stop thread.
    3. For blocking IO processing, use Interruptiblechannel instead of blocking IO as much as possible.
Summarize:

It's not easy to get tasks and threads to stop safely, quickly, and reliably. Java does not provide any mechanism to safely terminate a thread. But it provides interrupts (interruption), which is a collaborative mechanism that enables one thread to terminate the work of another thread. --"Java Concurrent Programming Combat" chapter 7th cancel and close p111

Interrupts are a collaborative mechanism. One thread cannot force other threads to stop the operation being performed to perform other operations. When thread A interrupts B, a simply requires B to stop executing at a point where it can be paused-provided that thread B is willing to stop. --"Java Concurrent Programming Combat" 5th Chapter basic Building Module p77

In summary, interrupts are just a collaborative mechanism that requires interrupted threads to handle interrupts themselves. Stopping a thread best practice is an interrupt + condition variable.

How to stop a running Java thread

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.