Today, we talk about how to gracefully end a thread! According to my recent statistics, there are nearly 10W+ reading volume for a single article on the interview questions related to this topic. Therefore, I recommend it to you!

To stop a thread means to stop the action you are doing before the task has finished processing it, i.e. to abandon the current action. The thread.stop () method can be used to stop a Thread, but it is best not to use it.

While it does stop a running thread, this method is unsafe and deprecated. There are three ways to terminate a running thread in Java:

  1. Use exit flags to allow the thread to exit normally, that is, to terminate when the run method completes.
  2. Use the stop method to force termination, but it is not recommended because stop, like suspend and resume, is an expired method.
  3. Interrupt a thread with the interrupt method.

1. Threads that cannot be stopped

The effect of the interrupt() method is not to stop the loop as quickly as the for+break statement. Calling interrupt puts a stop mark on the current thread, not actually stopping it. \

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            System.out.println("i="+(i+1)); }}}public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();
        } catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Output result:

. i=499994
i=499995
i=499996
i=499997
i=499998
i=499999
i=500000
Copy the code

2. Check whether the thread is stopped

The Thread. Java class provides two methods: \

  1. This.interrupted (): Tests whether the current thread has been interrupted;
  2. This.isinterrupted (): Tests whether the thread has been interrupted;

So what are the graphical differences between these two methods? The this.interrupted() method is used to test whether the current thread, which is the thread running this.interrupted(), has been interrupted.

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            i++;
// System.out.println("i="+(i+1));}}}public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();

            System.out.println("stop 1??" + thread.interrupted());
            System.out.println("stop 2??" + thread.interrupted());
        } catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Running results:

stop 1??false
stop 2??false
Copy the code

The run.java class calls the following code on the Thread object: Thread.interrupt (), which is later used.

System.out.println("stop 1??" + thread.interrupted());
System.out.println("stop 2??" + thread.interrupted());
Copy the code

For example, after the interruption () method tests whether the current thread has been interrupted. For example, after the interruption () method tests whether the thread has been interrupted.

The current thread is main, which never interrupts, so it prints two false.

How do you make the main thread interrupt?

public class Run2 {
    public static void main(String args[]){
        Thread.currentThread().interrupt();
        System.out.println("stop 1??" + Thread.interrupted());
        System.out.println("stop 2??" + Thread.interrupted());

        System.out.println("End"); }}Copy the code

The running effect is as follows:

stop 1??true
stop 2??false
End
Copy the code

The interrupted() method does determine if the current thread is stopped. But why is the second Boolean false? The official help documentation explains the interrupted method: Tests whether the current thread has been interrupted. The interrupted state of the thread is cleared by this method. In other words, if this method is called twice in a row, the second call returns false.

Now look at the inInterrupted() method.

public class Run3 {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        thread.interrupt();
        System.out.println("stop 1??" + thread.isInterrupted());
        System.out.println("stop 2??"+ thread.isInterrupted()); }}Copy the code

Running results:

stop 1??true
stop 2??true
Copy the code

IsInterrupted () and is in clear state, so prints two true.

3. Thread that can be stopped — exception method

Use the for statement to check whether the thread is stopped or not. If it is stopped, the following code will not run: \

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("Thread terminated, for loop no longer executes");
                break;
            }
            System.out.println("i="+(i+1)); }}}public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();
        } catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Running results:

. i=202053
i=202054
i=202055
i=202056The thread has terminated,forLoop no longer executesCopy the code

The example above stops the thread, but if there are more statements below the for statement, it will continue to run. Look at the following example:

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("Thread terminated, for loop no longer executes");
                break;
            }
            System.out.println("i="+(i+1));
        }

        System.out.println("This is the statement outside of the for loop that will also be executed."); }}Copy the code

The result of execution with run.java is:

. i=180136
i=180137
i=180138
i=180139The thread has terminated,forThe loop no longer executes this isforThe statements outside the loop will also be executedCopy the code

How do I solve the problem of the statement continuing to run? Take a look at the updated code:

public class MyThread extends Thread {
    public void run(){
        super.run();
        try {
            for(int i=0; i<500000; i++){
                if(this.interrupted()) {
                    System.out.println("Thread terminated, for loop no longer executes");
                        throw new InterruptedException();
                }
                System.out.println("i="+(i+1));
            }

            System.out.println("This is the statement outside of the for loop that will also be executed.");
        } catch (InterruptedException e) {
            System.out.println(MyThread. Java class catch...); e.printStackTrace(); }}}Copy the code

The result of running run.java is as follows:

. i=203798
i=203799
i=203800The thread has terminated,forThe loop no longer executes into the myThread. Java classcatchThe... java.lang.InterruptedException at thread.MyThread.run(MyThread.java:13)
Copy the code

4. Stop in a deep sleep

What happens if the thread stops in the sleep() state? \

public class MyThread extends Thread {
    public void run(){
        super.run();

        try {
            System.out.println("Thread started...");
            Thread.sleep(200000);
            System.out.println("Thread terminated.");
        } catch (InterruptedException e) {
            System.out.println("After being stopped in sleep, enter catch and call isInterrupted() as a result:+ this.isInterrupted()); e.printStackTrace(); }}}Copy the code

The result of running run.java is:

Thread start... To be stopped in sleep, to entercatchThe result of calling isInterrupted() is:false
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at thread.MyThread.run(MyThread.java:12)
Copy the code

From the printed results, if a thread is stopped in the sleep state, a catch statement is entered and the stop state value is cleared to false.

In contrast to the previous experiment, where sleep is followed by interrupt(), remember to learn:

public class MyThread extends Thread {
    public void run(){
        super.run();
        try {
            System.out.println("Thread started...");
            for(int i=0; i<10000; i++){
                System.out.println("i=" + i);
            }
            Thread.sleep(200000);
            System.out.println("Thread terminated.");
        } catch (InterruptedException e) {
             System.out.println("Stop, sleep, catch exception."); e.printStackTrace(); }}}public class Run {
    public static void main(String args[]){
        Thread thread = newMyThread(); thread.start(); thread.interrupt(); }}Copy the code

Running results:

i=9998
i=9999First stop, then encounter sleep, entercatchAbnormal Java. Lang. InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at thread.MyThread.run(MyThread.java:15)
Copy the code

5. Stopable threads — violence stops

Using the stop() method to stop a thread is very violent. \

public class MyThread extends Thread {
    private int i = 0;
    public void run(){
        super.run();
        try {
            while (true){
                System.out.println("i=" + i);
                i++;
                Thread.sleep(200); }}catch(InterruptedException e) { e.printStackTrace(); }}}public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
        Thread.sleep(2000); thread.stop(); }}Copy the code

Running results:

i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9

Process finished with exit code 0
Copy the code

6. Stop and ThreadDeath exceptions

A java.lang.threadDeath exception is thrown when the stop() method is called, but normally this exception does not need to be caught explicitly. \

public class MyThread extends Thread {
    private int i = 0;
    public void run(){
        super.run();
        try {
            this.stop();
        } catch (ThreadDeath e) {
            System.out.println("Enter an exception catch"); e.printStackTrace(); }}}public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = newMyThread(); thread.start(); }}Copy the code

The stop() method is also invalidated because forcing the thread to stop might prevent some rational work from being completed. Another situation is to unlock the locked object, resulting in data synchronization processing, data inconsistency problem.

7. Adverse consequences of lock release

Releasing the lock using stop() will result in inconsistent data results. If such a situation occurs, the data processed by the program may be damaged, and eventually lead to the process error of the program execution, special attention must be paid to: \

public class SynchronizedObject {
    private String name = "a";
    private String password = "aa";

    public synchronized void printString(String name, String password){
        try {
            this.name = name;
            Thread.sleep(100000);
            this.password = password;
        } catch(InterruptedException e) { e.printStackTrace(); }}public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(Stringpassword) { this.password = password; }}public class MyThread extends Thread {
    private SynchronizedObject synchronizedObject;
    public MyThread(SynchronizedObject synchronizedObject){
        this.synchronizedObject = synchronizedObject;
    }

    public void run(){
        synchronizedObject.printString("b"."bb"); }}public class Run {
    public static void main(String args[]) throws InterruptedException {
        SynchronizedObject synchronizedObject = new SynchronizedObject();
        Thread thread = new MyThread(synchronizedObject);
        thread.start();
        Thread.sleep(500);
        thread.stop();
        System.out.println(synchronizedObject.getName() + ""+ synchronizedObject.getPassword()); }}Copy the code

Output result:

b  aa
Copy the code

Because the stop() method and the methods marked “expired/obsolete” in the JDK are clearly functionally flawed, it is not recommended to use the stop() method in applications.

8. Use return to stop the thread

The combination of interrupt() and return also stops the thread: \

public class MyThread extends Thread {
    public void run(){
        while (true) {if(this.isInterrupted()){
                System.out.println("Thread stopped!");
                return;
            }
            System.out.println("Time: "+ System.currentTimeMillis()); }}}public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
        Thread.sleep(2000); thread.interrupt(); }}Copy the code

Output result:

. Time:1467072288503
Time: 1467072288503
Time: 1467072288503Thread stopped!Copy the code

However, it is recommended to use a “throw exception” method to stop a thread, because exceptions can also be thrown up in a catch block, allowing the thread stop event to propagate.

From: home.cnblogs.com/u/wenjunwei/