Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

Author’s other platforms:

| CSDN:blog.csdn.net/qq_4115394…

| the nuggets: juejin. Cn/user / 651387…

| zhihu: www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| public no. : 1024 notes

This article is about 6,136 words and takes 10 minutes to read

1 introduction

The previous article on threads and their common methods introduced the use of threads. In addition to stopping a thread after it completes its task, there are ways to intervene to stop it. Stopping a thread means ending the operation it is performing before its processing completes the task.

There are three ways to terminate a thread in Java.

2 the body

1. Use exit signs

Use exit flags to allow the thread to exit normally, that is, to terminate when the run method completes.

When the run method completes, the thread exits. But sometimes the run method never ends. Such as using threads in a server program to listen for client requests, or other tasks that require loop processing. In this case, it is common to put these tasks in a loop, such as a while loop. Such as:

package com.jiangxia.chap1; ** ** Jiangxia * date: 2021-04-15 */ public class Demo12 { public static void main(String[] args) throws InterruptedException { Demo12Thread t = new Demo12Thread(); t.start(); Thread.sleep(2000); t.stopThread(); } } class Demo12Thread extends Thread{ private boolean flag = true; @Override public void run() { try { while (flag){ System.out.println("Time="+System.currentTimeMillis()); Thread.sleep(1000); } system.out.println (" thread ends "); }catch (InterruptedException e){ e.printStackTrace(); Public void stopThread(){// Flase flag = false; }}Copy the code

2. The stop method forces the thread to end

The Java class provides the thread.stop () method to stop a Thread, and while it does stop a running Thread, this method is unsafe and deprecated. The java.lang.threadDeath exception is thrown when the stop() method is called. The official documentation explains it as follows:

This method is inherently unsafe. Stopping a thread with thread.stop() causes the release (unlocking) of all monitors that the thread has locked due to an unchecked ThreadDeath exception propagating up the stack. If any object previously protected by these monitors is in an inconsistent state, the object in the inconsistent state (the damaged object) will be visible to other threads, which can lead to arbitrary behavior.

package com.jiangxia.chap1; ** * Jiangxia * date: 2021-04-15 */ public class Demo13 { public static void main(String[] args) throws InterruptedException { Thread t = new Demo13Thread(); t.start(); Thread.sleep(2000); // This method has a delete line indicating that it has been deleted. }} class Demo13Thread extends Thread{@override public void run() {try{while(true){system.out.println ("run "method Time="+System.currentTimeMillis()); Thread.sleep(1000); } }catch (InterruptedException e){ e.printStackTrace(); }catch (ThreadDeath ThreadDeath){system.out.println (" enter the catch block "); threadDeath.printStackTrace(); }}}Copy the code

According to idea, it can be found that the stop method has a deletion line, indicating that the stop method has been invalid. If threads are forced to stop, some rational work may not be completed. Another reason is that the locked object is “unlocked”, which results in different data synchronization and data inconsistency. Using stop() to stop a thread is very violent, and because stop() and methods marked “expired/invalid” in the JDK are functionally flawed, stop() is not recommended in applications. Such as:

package com.jiangxia.chap1; public class Demo14 { public static void main(String[] args) throws InterruptedException { Demo14Info info = new Demo14Info(); Thread t = new Demo14Thread(info); t.start(); Thread.sleep(200); t.stop(); // Since the stop method terminates the thread, only the value of username is updated, System.out.println("username="+info.getUsername()+":password="+info.getPassword()); } } class Demo14Thread extends Thread{ private Demo14Info info; public Demo14Thread(Demo14Info info){ this.info = info; } @override public void run() {info.updateinfo (" updateInfo ","1111111"); }} class Demo14Info{private String username=" Demo14Info "; private String password="222222"; public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } synchronized public void updateInfo(String username,String password){ try { this.username = username; Thread.sleep(1000); this.password = password; } catch (InterruptedException e) { e.printStackTrace(); }}}Copy the code

Because the stop method terminates the thread, the code above only updates the value of username, and the value of password remains unchanged.

Use the interrupt method to interrupt the thread

Note that this Thread is not necessarily the current Thread, but the Thread represented by the Thread instance calling the method. Calling interrupt does not actually end the Thread. If a stop mark is placed on the current Thread, the Thread will continue running.

The Thread class provides a method that tests whether the current Thread has interrupted, checks for interruptions, returns a Boolean value and clears the interrupted status. The second time the interrupted status is known, it returns false.

The isInterrupted method tests whether a thread has been interrupted without clearing the interrupted state.

A summary of these three methods can be summarized as follows:

Public void thread.interrupt () // No return value public Boolean thread.isinterrupted () // Return value public static Boolean Thread.interrupted() // Static with a return valueCopy the code

Such as:

package com.jiangxia.chap1; ** * Jiangxia * date: 2021-04-15 */ public class Demo15 { public static void main(String[] args) { Thread thread = new Thread15(); thread.start(); Thread.interrupt (); thread.interrupt(); } } class Thread15 extends Thread{ @Override public void run() { for(int i=0; i<1000; I ++){system.out.println ("run method: I ="+ I); }}}Copy the code

Calling the interrupt method does not actually terminate the thread, but marks the current thread with a stop flag.

package com.jiangxia.chap1; /** * Interrupted by interruption * author: Jiangxia * date: 2021-04-15 */ public class Demo15 { public static void main(String[] args) { Thread thread = new Thread15(); thread.start(); Thread.interrupt (); thread.interrupt(); System.out.println(" + thread.isinterrupted ()); System.out.println(" + thread.interrupted ()); } } class Thread15 extends Thread{ @Override public void run() { for(int i=0; i<1000; I ++){system.out.println ("run method: I ="+ I); }}}Copy the code

The thread.isInterrupted method checks whether Thread15 is marked as stopped.

The thread. interrupted method checks whether the main Thread is marked as stopped.

The only difference between interrupted() and isInterrupted() is that the former reads and clears the interrupted state, while the latter reads only the state.

Tests whether the current thread has been interrupted. The status of the interrupted thread is cleared by this method. If this method is called twice in a row, the second call returns false.

package com.jiangxia.chap1; public class Demo17 { public static void main(String[] args) throws InterruptedException { Thread thread = new Thred17(); // Start the thread thread.start(); //Thread.sleep(1000); thread.interrupt(); } } class Thred17 extends Thread{ @Override public void run() { for (int i = 0; i <1000 ; I++){if(this.isinterrupted ()){system.out.println (" this isInterrupted! ); break; } System.out.println("i="+i); } system.out.println (" Here is the code after the loop ends "); }}Copy the code

If the thread has sleep code, regardless of whether it is in the sleep state, an exception message is raised if the interrupt method is called. Such as:

package com.jiangxia.chap1; public class Demo17 { public static void main(String[] args) throws InterruptedException { Thread thread = new Thred17(); // Start the thread thread.start(); //Thread.sleep(1000); thread.interrupt(); } } class Thred17 extends Thread{ @Override public void run() { try{ for (int i = 0; i <1000 ; I++){if(this.isinterrupted ()){system.out.println (" this isInterrupted! ); // If you use break, other threads will not know about it. throw new InterruptedException(); } System.out.println("i="+i); } system.out.println (" Here is the code after the loop ends "); }catch (InterruptedException e){ e.printStackTrace(); }}}Copy the code

package com.jiangxia.chap1; public class Demo18 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread18(); t.start(); Thread.sleep(20); t.interrupt(); } } class Thread18 extends Thread{ @Override public void run() { try { for (int i = 0; i < Integer.MAX_VALUE; i++) { String s = new String(); } system.out.println (" start thread "); Thread.sleep(20000); System.out.println(" end thread "); }catch (InterruptedException e){system.out.println (" exception enters the catch block "); e.printStackTrace(); }}}Copy the code

3 summary

These are the three ways Java can stop a thread. There is no mechanism provided in Java to safely terminate threads. The stop method has been deprecated because it is unsafe. But Java provides Interruption, which is a cooperative mechanism that can cause one thread to terminate the work of another thread. In addition, the thread execution can be controlled by setting exit flags outside, the state of variables can be checked inside the thread, and the execution can be controlled by changing the value of variables outside.

Related recommendations:

  • Common apis for multithreaded programming threads

  • Threads and common methods for threads

  • Six states of a thread

  • Volatile keyword resolution for Java concurrent programming