How to interrupt Java threads

Source: Internet
Author: User
Tags socket blocking
Program Is simple. However, in front of programmers, multithreading presents a new set of difficulties. If it is not properly solved, it will lead to unexpected behavior and subtle and hard-to-find errors.
In this article Article To address one of these challenges: How to interrupt a running thread.

Background
Interrupt means that the thread stops all ongoing operations before the thread completes the task, effectively suspending its current operation. Whether the thread is dead or waiting for a new task or continues to run to the next step depends on this program. Although it may seem simple for the first time, you must make some warnings to achieve the expected results. You 'd better keep in mind the following tips.

First, forget the thread. Stop method. Although it does stop a running thread, this method is neither secure nor advocate, which means that it will no longer exist in future Java versions.


Some rash guys may be confused by another method thread. Interrupt. Although its name seems to imply something, this method does not interrupt a running thread (which will be further explained later), as described in listing. It creates a thread and tries to use the thread. interrupt method to stop the thread. The call of the thread. Sleep () method provides ample time for thread initialization and suspension. The thread itself is not involved in any useful operations.

Class example1 extends thread {Boolean stop = false; public static void main (string ARGs []) throws exception {example1 thread = new example1 (); system. out. println ("Starting thread... "); thread. start (); thread. sleep (1, 3000); system. out. println ("interrupting thread... "); thread. interrupt (); thread. sleep (1, 3000); system. out. println ("Stopping application... "); // system. exit (0);} public void run () {While (! Stop) {system. out. println ("thread is running... "); long time = system. currenttimemillis (); While (system. currenttimemillis ()-time <1000) {}} system. out. println ("thread exiting under request... ");}}

If you runCode, You will see the following output in the console:

Starting thread...

Thread is running...

Thread is running...

Thread is running...

Interrupting thread...

Thread is running...

Thread is running...

Thread is running...

Stopping application...

Thread is running...

Thread is running...

Thread is running...
...............................
Even after thread. Interrupt () is called, the thread continues to run.

Truly interrupt a thread

The best way to interrupt a thread is to use shared variable to send a signal that the thread must stop a running task. The thread must periodically check this variable (especially during redundant operations) and then stop the task in order. Listing B describes this method.

Listing B
Class example2 extends thread {

Volatile Boolean stop = false;

Public static void main (string ARGs []) throws exception {

Example2 thread = new example2 ();

System. Out. println ("Starting thread ...");

Thread. Start ();

Thread. Sleep (3000 );

System. Out. println ("asking thread to stop ...");

Thread. Stop = true;

Thread. Sleep (3000 );

System. Out. println ("Stopping application ...");

// System. Exit (0 );

}

Public void run (){

While (! Stop ){

System. Out. println ("thread is running ...");

Long time = system. currenttimemillis ();

While (system. currenttimemillis ()-time <1000 )&&(! Stop )){

}

}

System. Out. println ("thread exiting under request ...");

}

}
 
Running the code in listing B will generate the following output (note how the thread exits in an orderly manner)

Starting thread...

Thread is running...

Thread is running...

Thread is running...

Asking thread to stop...

Thread exiting under request...

Stopping application...

Although this method requires some encoding, it is not difficult to implement it. At the same time, it gives the thread the opportunity to clean up the necessary work, which is absolutely required in any multi-threaded application. Make sure to define the shared variable as the volatile type or block all its access to the synchronized block/method (synchronized blocks/methods.

So far everything went well! However, what happens when the thread is blocked while waiting for some events? Of course, if a thread is blocked, it cannot check shared variables and stop. This may occur in many cases, such as calling object. Wait (), serversocket. Accept (), and datagramsocket. Receive.

They may all permanently block threads. Even if a timeout occurs, it is not feasible or appropriate to wait until the timeout period expires. Therefore, you must use a mechanism to exit the blocked state of the thread earlier.

Unfortunately, there is no such mechanism that applies to all situations, but specific technologies can be used based on different situations. In the following sections, I will explain the most common examples.

Use thread. Interrupt () to interrupt the thread

As described in listing a, the thread. Interrupt () method does not interrupt a running thread. In fact, this method throws an interrupt signal when the thread is blocked, so that the thread can exit the blocking state. More specifically, if the thread is. wait, thread. join and thread. if sleep is blocked by one of the three methods, it will receive an interrupt exception (interruptedexception) to terminate the blocked state early.

Therefore, if the thread is blocked by the preceding methods, the correct way to stop the thread is to set the shared variable and call interrupt () (note that the variable should be set first ).If the thread is not blocked, calling interrupt () will not work; otherwise, the thread will get an exception (the thread must be prepared to handle this situation in advance) and then escape from the blocking state.In either case, the last thread checks the shared variable and stops. The listing c example describes the technology.

Listing c
Class example3 extends thread {

Volatile Boolean stop = false;

Public static void main (string ARGs []) throws exception {

Example3 thread = new example3 ();

System. Out. println ("Starting thread ...");

Thread. Start ();

Thread. Sleep (3000 );

System. Out. println ("asking thread to stop ...");

Thread. Stop = true; // If the thread is blocked, this variable is not checked.

Thread. Interrupt ();

Thread. Sleep (3000 );

System. Out. println ("Stopping application ...");

// System. Exit (0 );

}

Public void run (){

While (! Stop ){

System. Out. println ("thread running ...");

Try {

Thread. Sleep (1000 );

} Catch (interruptedexception e ){

System. Out. println ("thread interrupted ...");

}

}

System. Out. println ("thread exiting under request ...");

}

}

Once the thread. Interrupt () in listing C is called, the thread receives an exception and escapes the blocking status and determines that it should be stopped. Run the above code to get the following output:

Starting thread...

Thread running...

Thread running...

Thread running...

Asking thread to stop...

Thread interrupted...

Thread exiting under request...

Stopping application...

Interrupt I/O operations
However, what if the thread is blocked during I/O operations? I/O operations can block threads for a long period of time, especially when network applications are involved. For example, a server may have to wait for a request, or a network application may have to wait for the response from a remote host.

If you are using channel (channels) (this is the new I/O API introduced in Java 1.4), the blocked thread will receive a closedbyinterruptexception exception. In this case, the logic of the Code is the same as that in the third example, but the exception is different.

However, you may be using the traditional I/O that existed before java1.0, and require more work. In this case, thread. Interrupt () does not work because the thread will not exit the blocked state. Listing D describes this line. Even if interrupt () is called, the thread will not exit the blocked state.

Listing d
Import java. Io .*;

Class example4 extends thread {

Public static void main (string ARGs []) throws exception {

Example4 thread = new example4 ();

System. Out. println ("Starting thread ...");

Thread. Start ();

Thread. Sleep (3000 );

System. Out. println ("interrupting thread ...");

Thread. Interrupt ();

Thread. Sleep (3000 );

System. Out. println ("Stopping application ...");

// System. Exit (0 );

}

Public void run (){

Serversocket socket;

Try {

Socket = new serversocket (7856 );

} Catch (ioexception e ){

System. Out. println ("cocould not create the socket ...");

Return;

}

While (true ){

System. Out. println ("waiting for connection ...");

Try {

Socket sock = socket. Accept ();

} Catch (ioexception e ){

System. Out. println ("accept () failed or interrupted ...");

}

}

}

}

Fortunately, the Java platform provides a solution for this situation, that is, to call the close () method of the socket blocking this thread. In this case, if the thread is blocked by I/O operations, the thread will receive a socketexception, which is very similar to the interruptedexception exception thrown by the interrupt () method.

The only thing to note is that the reference of the socket must exist. Only in this way can the close () method be called. This means that the socket object must be shared. Listing E describes this situation. The running logic is the same as the previous example.

Listing E
Import java.net .*;
Import java. Io .*;
Class example5 extends thread {
Volatile Boolean stop = false;
Volatile serversocket socket;
Public static void main (string ARGs []) throws exception {
Example5 thread = new example5 ();
System. Out. println ("Starting thread ...");
Thread. Start ();
Thread. Sleep (3000 );
System. Out. println ("asking thread to stop ...");
Thread. Stop = true;
Thread. Socket. Close ();
Thread. Sleep (3000 );
System. Out. println ("Stopping application ...");
// System. Exit (0 );
}
Public void run (){
Try {
Socket = new serversocket (7856 );
} Catch (ioexception e ){
System. Out. println ("cocould not create the socket ...");
Return;
}
While (! Stop ){
System. Out. println ("waiting for connection ...");
Try {
Socket sock = socket. Accept ();
} Catch (ioexception e ){
System. Out. println ("accept () failed or interrupted ...");
}
}
System. Out. println ("thread exiting under request ...");
}
}
The output after running the code in listing e is as follows:

Starting thread...

Waiting for connection...

Asking thread to stop...

Accept () failed or interrupted...

Thread exiting under request...

Stopping application...

Multithreading is a powerful tool, but it presents a series of difficulties. One of them is how to interrupt a running thread. If implemented properly, using the above technology to interrupt the thread will be easier than using the embedded operations already provided on the Java platform.

========================================================== ====

Writing multithreaded programs in Java, with its built-in support for threads, is fairly straightforward. however, multithreading presents a whole set of new challenges to the programmer that, if not correctly addressed, can lead to unexpected behavior and subtle, hard-to-find errors. in this article, we address one of those challenges: how to interrupt a running thread.

Background
Interrupting a thread means stopping what it is doing before it has completed its task, wait tively aborting its current operation. whether the thread dies, waits for new tasks, or goes on to the next step depends on the application.

Although it may seem simple at first, you must take some precautions in order to achieve the desired result. There are some caveats you must be aware of as well.

First of all, forgetThread. StopMethod. Although it indeed stops a running thread, the method is unsafe and was deprecated, which means it may not be available in future versions of the Java.

another method that can be confusing for the unadvised is thread. interrupt . despite what its name may imply, the method does not interrupt a running thread (more on this later), as listing ademonstrates. it creates a thread and tries to stop it using thread. interrupt . the callto thread. sleep ( ) give plenty of time for the thread initialization and termination. the thread itself does not do anything useful.

If you run the code in listing a, you shoshould see something like this on your console:
Starting thread...
Thread is running...
Thread is running...
Thread is running...
Interrupting thread...
Thread is running...
Thread is running...
Thread is running...
Stopping application...

Even afterThread. Interrupt()Is called, the thread continues to run for a while.

Really interrupting a thread
The best, recommended way to interrupt a thread is to use a shared variable to signal that it must stop what it is doing. the thread must check the variable periodically, especially during lengthy operations, and terminate its task in an orderly manner. listing B demonstrates this technique.

Running the code in listing B will generate output like this (Notice how the thread exits in an orderly fashion ):
Starting thread...
Thread is running...
Thread is running...
Thread is running...
Asking thread to stop...
Thread exiting under request...
Stopping application...

Although this method requires some coding, it is not difficult to implement and give the thread the opportunity to do any cleanup needed, which is an absolute requirement for any multithreaded application. just be sure to declare the shared variableVolatileOr enclose any access to itSynchronizedBlocks/methods.

So far, so good! But what happens if the thread is blocked waiting for some event? Of course, if the thread is blocked, it can't check the shared variable and can't stop. There are plenty of situations when that may occur, such as callingObject. Wait(),Serversocket. Accept(), AndDatagramsocket. Receive(), To name a few.

They all can block the thread forever. even if a timeout is employed, it may not be feasible or desirable to wait until the timeout expires, so a mechanic to prematurely exit the blocked state must be used.

Unfortunately there is no such mechanic that works for all cases, but the participating technique to use depends on each situation. In the following sections, I'll give solutions for the most common cases.

interrupting a thread with thread. interrupt ()
as demonstrated in listing a, the method thread. interrupt () does not interrupt a running thread. what the method actually does is to throw an interrupt if the thread is blocked, so that it exits the blocked state. more precisely, if the thread is blocked at one of the methods object. wait , thread. join , or thread. sleep , it has es An interruptedexception , thus terminating the blocking method prematurely.

SO, if a thread blocks in one of the aforementioned methods, the correct way to stop it is to set the shared variable and then call the interrupt () Method on it (notice that it is important to set the variable first ). if the thread is not blocked, calling interrupt ( ) will not hurt; otherwise, the thread will get an exception (the thread must be prepared to handle this condition) and escape the blocked state. in either case, eventually the thread will test the shared variable and stop. listing C is a simple example that demonstrates this technique.

as soon as thread. interrupt () is called in listing C, the thread gets an exception so that it escapes the blocked state and determines that it shoshould stop. running this code produces output like this:
starting thread...
thread running...
thread running...
thread running...
asking thread to stop...
thread interrupted...
thread exiting under request...
stopping application...

Interrupting an I/O operation
But what happens if the thread is blocked on an I/O operation? I/O can block a thread for a considerable amount of time, fig if network communication is involved. for example, a server may be waiting for a request, or a network application may be waiting for an answer from a remote host.

If you're using channels, available with the new I/O API introduced in Java 1.4, the blocked thread will getClosedbyinterruptexceptionException. If that is the case, the logic is the same as that used in the third example-only the exception is different.

But you might be using the traditional I/O available since Java 1.0, since the new I/O is so recent and requires more work. In this case,Thread. Interrupt()Doesn't help, since the thread will not exit the blocked state. Listing D demonstrates that behavior. AlthoughInterrupt ()Method is called, the thread does not exit the blocked state.

Fortunately, the Java platform provides a solution for that case by callingClose ()Method of the socket the thread is blocked in. In this case, if the thread is blocked in an I/O operation, the thread will getSocketexceptionException, much likeInterrupt ()Method causesInterruptedexceptionTo be thrown.

The only caveat is that a reference to the socket must be available so that itsClose ()Method can be called. That means the socket object must also be shared. Listing E demonstrates this case. The logic is the same as in the examples presented so far.

And here's the sample output you can expect CT from running listing E:
Starting thread...
Waiting for connection...
Asking thread to stop...
Accept () failed or interrupted...
Thread exiting under request...
Stopping application...

multithreading is a powerful tool, but it presents its own set of challenges. one of these is how to interrupt a running thread. if properly implemented, these techniques make interrupting a thread no more difficult than using the built-in operations already provided by the Java platform.

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.