Tencent Interviewer: How to stop a running thread? I look blinded. . .

Stop means operating in a thread before the task processed stopped doing the task, which is to abandon the current operation. Stop a thread can use Thread.stop () method, but it is best not to use it. Although it does stop a running thread, but this method is unsafe, but is deprecated methods. There are java in the following three ways to terminate a running thread:

  1. Use exit signs, the thread exits normally, that is, after the completion of the thread run method terminates.

  2. Use stop forced termination method, but this method is not recommended, because the stop and suspend and resume are the same as outdated methods obsolete.

  3. Use interrupt method interrupt thread.

1. can not stop thread

Use effect interrupt () method is not as for + break statement that, immediately stop the loop. Call interrupt method is to hit a stop sign in the current thread, not really stop the thread.

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();
        }
    }
}

Output:

...
i=499994
i=499995
i=499996
i=499997
i=499998
i=499999
i=500000

2. Thread determine whether to stop state

Thread.java class provides two methods:

  1. this.interrupted (): test whether the current thread has been interrupted;

  2. this.isInterrupted (): Tests whether this thread has been interrupted;

So what difference does it view of these two methods? Let's take a look at the interpretation this.interrupted () method: test whether the current thread has been interrupted, the current thread refers to the thread running this.interrupted () method.

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();
        }
    }
}

operation result:

stop 1??false
stop 2??false

Although class Run.java calling thread object code on the following: thread.interrupt (), and later use

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

To determine whether the object is represented by a thread thread stops, but the Print Console view, did not stop the thread, which also proved to explain interrupted () method to test whether the current thread has been interrupted. The current thread is the main, it never stopped, so the printed result is two false.

How to make the main thread interrupt effect?

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");
    }
}

Operating results as follows:

stop 1??true
stop 2??false
End

Methods interrupted () really judge whether the current thread is stopped. But why the first two boolean value is false it? The official explanation of the interrupted Help documentation methods: Tests whether the current thread has been interrupted. Thread's interrupt status is cleared by this method.  In other words, if the method is called twice in a row, the second call returns false.

The following look at 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());
    }
}

operation result:

stop 1??true
stop 2??true

isInterrupted () and cleared, so print two true.

3. Can Stop thread - Exception Act

With the knowledge learned in the previous point, the thread can be used for statements to determine what the thread is stopped, if it is stopped, then the code behind can no longer run:

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("线程已经终止, for循环不再执行");
                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();
        }
    }
}

operation result:

...
i=202053
i=202054
i=202055
i=202056
线程已经终止, for循环不再执行

Although the above example to stop the thread, but if there is the following statement for statement, will continue to run. See the examples below:

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("线程已经终止, for循环不再执行");
                break;
            }
            System.out.println("i="+(i+1));
        }

        System.out.println("这是for循环外面的语句,也会被执行");
    }
}

Use Run.java execution results are:

...
i=180136
i=180137
i=180138
i=180139
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行

How to solve the problem statements continue to run it? 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("线程已经终止, for循环不再执行");
                        throw new InterruptedException();
                }
                System.out.println("i="+(i+1));
            }

            System.out.println("这是for循环外面的语句,也会被执行");
        } catch (InterruptedException e) {
            System.out.println("进入MyThread.java类中的catch了。。。");
            e.printStackTrace();
        }
    }
}

Use Run.java operating results are as follows:

...
i=203798
i=203799
i=203800
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedException
 at thread.MyThread.run(MyThread.java:13)

4. Stop the sleeping

If the thread to stop the thread in the sleep () state, what would be the effect?

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

        try {
            System.out.println("线程开始。。。");
            Thread.sleep(200000);
            System.out.println("线程结束。");
        } catch (InterruptedException e) {
            System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());
            e.printStackTrace();
        }

    }
}

The results using Run.java are running:

线程开始。。。
在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at thread.MyThread.run(MyThread.java:12)

From the results of the printing point of view, if you stop a thread in a sleep state, will enter the catch statement, and clears the stop state value, making it a false.

Before a test is to sleep and then use the interrupt () to stop, as opposed to the operation should pay attention to the learning process:

public class MyThread extends Thread {
    public void run(){
        super.run();
        try {
            System.out.println("线程开始。。。");
            for(int i=0; i<10000; i++){
                System.out.println("i=" + i);
            }
            Thread.sleep(200000);
            System.out.println("线程结束。");
        } catch (InterruptedException e) {
             System.out.println("先停止,再遇到sleep,进入catch异常");
            e.printStackTrace();
        }

    }
}

public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        thread.interrupt();
    }
}

operation result:

i=9998
i=9999
先停止,再遇到sleep,进入catch异常
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at thread.MyThread.run(MyThread.java:15)

5. Be able to stop the violence, stop the thread ---

Using the stop () method stops the 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();
    }
}

operation result:

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

6. Method stop () with the exception java.lang.ThreadDeath

Java.lang.ThreadDeath will throw an exception when you call the stop () method, but under normal circumstances, this exception does not need to explicitly capture.

public class MyThread extends Thread {
    private int i = 0;
    public void run(){
        super.run();
        try {
            this.stop();
        } catch (ThreadDeath e) {
            System.out.println("进入异常catch");
            e.printStackTrace();
        }
    }
}

public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
    }
}

stop () method and void, as if to force the thread to stop some of the work has the potential to clean up the property can not be completed. Another case is that of unlocking a locked object, resulting in data processing are not synchronized, inconsistent data problems.

7. Release the lock of adverse consequences

Use stop () to release the lock will cause the results to data inconsistency. If this happens, the data processing program, there may be damaged, leading to erroneous program execution process, we must pay special attention 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(String password) {
        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());
    }
}

Output:

b  aa

Since the stop () method and are marked as "expired / invalid" in the JDK way, obviously it has a defect in function, it is not recommended to use stop () method in the program sheets.

8. Use the return stop thread

The method interrupt () using the return combination can achieve the effect of stopping the thread:

public class MyThread extends Thread {
    public void run(){
        while (true){
            if(this.isInterrupted()){
                System.out.println("线程被停止了!");
                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();
    }
}

Output:

...
Time: 1467072288503
Time: 1467072288503
Time: 1467072288503
线程被停止了!

However, it is recommended to use "throw an exception" to achieve the thread to stop, because you can also throw up an exception in the catch block, the thread to stop the event to spread.

Published 50 original articles · won praise 1706 · Views 2.22 million +

Guess you like

Origin blog.csdn.net/zl1zl2zl3/article/details/105326795