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. |