Thread to stop, interrupt Best Practices

How to stop the thread right

1. explain the principles of

Principle Description: Use interrupt to inform, rather than mandatory. What are the principles of Java threads are stopped?

In Java, the best way to stop the thread is using the interrupt interrupt, but this is just the thread will be notified to be terminated "You should stop running" and terminated the thread itself the power to decide (to decide whether and when to stop), depending on the stop request to stop the party and the party to comply with a convention good coding specification.

Start tasks and threads easily. Most of the time, we will let them run until the end, or let them stop on their own. However , sometimes we want to advance the end of the task, or thread, perhaps because the user canceled the operation or service needs to be shut down quickly, or run out or wrong.

To make the task and thread-safe, fast and reliably stopped is not an easy task. Java does not provide any mechanism to safely terminate the thread. But it provides an interrupt (Interruption), which is a cooperative mechanism , allows one thread to terminate another thread's current work.

This collaborative approach is necessary, and we rarely want a task, thread or stop the service immediately, because it would immediately stop sharing data structures in an inconsistent state . In contrast, when using a collaborative way when you need to stop in the preparation of tasks and services, they will first clear the work currently being performed before closing. This provides greater flexibility, because the task of code than the code itself issued a cancellation request more clearly how to perform cleanup work .

End of Life (End- of-Lifecycle) will make the task of issues, as well as service design and implementation of programs such as the process becomes complicated, and this is very important in programming elements are often overlooked. One major difference between the good behavior of the software shipped with barely software is very well-behaved software can improve the handling of failures, closing and cancellation process.

This chapter provides a variety of mechanisms to achieve cancellation and interruption, and how to write tasks and services, to enable them to respond to the cancellation request .

2. Best Practices: How to stop the thread right

2.1 thread usually stop in what circumstances

1, run () method has finished running
2, there is an exception, and the thread that is not caught.
After the thread stops, occupied resources will be recovered jvm.

2.2 correct stopping method: interrupt

Under normal circumstances 2.2.1 How to Stop

package stopthreads;

/**
 * 描述: run()方法内没有sleep()和wait()方法时,停止线程。
 */

public class RightStopThreadWithoutSleep implements Runnable{

    public static void main(String[] args) {
        Thread thread = new Thread(new RightStopThreadWithoutSleep());
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

    }
    @Override
    public void run() {
        int num = 0;
        while (num <= Integer.MAX_VALUE / 2){
            if (!Thread.currentThread().isInterrupted() && num % 10000 == 0) {
                System.out.println(num + "是10000的倍数");
            }
            num++;
        }
        System.out.println("任务结束了。");
    }
}

复制代码

Note: thread.interrupt(); not mandatory interrupt thread, there must cooperate to the interrupted thread.
Namely: the need to add the code for the sub-thread:!Thread.currentThread().isInterrupted()

2.2.2 How to Stop the thread may be blocked

package stopthreads;

import static java.lang.Thread.*;

public class RightStopThreadWithSleep {
    
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = ()->{
            int num = 0;
            while (num <= 300){
                if (num % 100 == 0 && !currentThread().isInterrupted()){
                    System.out.println(num + "是100的整数倍");
                }
                num++;
            }
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(500);
        thread.interrupt();
    }

}

复制代码

The results are as follows:

2.2.3 If the thread after each iteration blocked

package stopthreads;

import static java.lang.Thread.currentThread;
import static java.lang.Thread.sleep;

/**
 * 描述:如果在执行过程中,每次循环都会调用sleep()或wait()等方法,那么...
 */
public class rightStopThreadWithSleepEveryLoop {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = ()->{
            int num = 0;
            try {
                while (num <= 10000){
                    if (num % 100 == 0 && !currentThread().isInterrupted()){
                        System.out.println(num + "是100的整数倍");
                    }
                    num++;
                    sleep(10);
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
    }

}

复制代码

try-catch issues within the while:

package stopthreads;

import static java.lang.Thread.currentThread;
import static java.lang.Thread.sleep;

public class CantInterrupt {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = ()->{
            int num = 0;

                while (num <= 10000){
                    if (num % 100 == 0 && !currentThread().isInterrupted()){
                        System.out.println(num + "是100的整数倍");
                    }
                    num++;
                    try {
                        sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

        };

        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
    }

}

复制代码

Change the try-catch position, the result is completely different:

Note: Even added on: && !currentThread().isInterrupted() still no effect!
The reason: the Thread class at design time, sleep () call to interrupt, interrupt markers are automatically cleared!

Best of both actual development practices 2.3

2.3.1 Best practice one: preferences: transmission blocked (the signature method throws an exception)

Let's add a little episode: incorrectly handle exceptions, the method is called in directly to InterruptExceptioncatch out, this is equivalent to the low-level approach to put an exception to swallow, leading to the upper call can not perceive that there is an exception.
The correct approach should be: throw an exception, and the exception handling really should be called a function call it that.
Error codes are as follows:

package stopthreads;

/**
 * 描述:  catch了InterruptionException之后的优先选择:在方法签名中抛出异常。
 * 那么,在run()中就会强制try-catch。
 */
public class RightWayStopThreadInProduction implements Runnable {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProduction());
        thread.start();
        thread.sleep(1000);
        thread.interrupt();
    }

    @Override
    public void run() {
        while(true){
            System.out.println("go");
            throwInMethod();
        }
    }

    private void throwInMethod() {

        /**
         * 错误做法:这样做相当于就把异常给吞了,导致上层的调用无法感知到有异常
         * 正确做法应该是,抛出异常,而异常的真正处理,应该叫个调用它的那个函数。
         */
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

复制代码

Error handling abnormal causes the thread can not be stopped:


The right approach: throw an exception, and the exception handling really should be called a function call it that.
Low-level method throws an exception, the caller only Surround with try / catch up.

The correct code is as follows:

package stopthreads;

import static java.lang.Thread.sleep;

/**
 * 描述:  catch了InterruptionException之后的优先选择:在方法签名中抛出异常。
 * 那么,在run()中就会强制try-catch。
 */
public class RightWayStopThreadInProduction implements Runnable {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProduction());
        thread.start();
        sleep(1000);
        thread.interrupt();
    }

    @Override
    public void run() {
        while(true){
            System.out.println("go");
            throwInMethod();
        }
    }

    private void throwInMethod() throws InterruptedException {

        /**
         * 错误做法:这样做相当于就把异常给吞了,导致上层的调用无法感知到有异常
         * 正确做法应该是,抛出异常,而异常的真正处理,应该叫个调用它的那个函数。
         */
       /* try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

       sleep(2000);

    }
}

复制代码

to sum up:

2.3.2 Best Practice two: do not want to or can not be delivered: Resume interrupted (again the man interrupted manually restore)

In the lower process may try-catch, but must be added Thread.currentThread () interrupt ().;

package stopthreads;

import static java.lang.Thread.sleep;

public class RightWayStopThreadInProduction2 implements Runnable{

    @Override
    public void run() {

        while(true){
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("线程中断");
                break;
            }
            reInterrupt();
        }

    }

    private void reInterrupt() {

        try {
            sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProduction2());
        thread.start();
        sleep(1000);
        thread.interrupt();
    }
}

复制代码

result:

Summary: If you can not throw interruption, how to do?

If you do not want to or can not be delivered InterruptedException(for example, when the run method, do not let the process throws InterruptedException), then you should choose to call in a catch clause Thread.currentThread() interrupt()to restore the interrupt state set, in order to still be able to check in a subsequent execution just was interrupted. Supra specific code, where the thread is interrupted during SLEEP, and caught by a catch to the interrupt and reset the interrupt state, so that the interrupt state can be detected when a next cycle, normal exit.

Should not mask interrupts

2.4 the right to stop benefits

3. Stop the ready-error method

4. important source analytic function

5. Frequently Asked Interview Questions

Guess you like

Origin juejin.im/post/5d6c8e23f265da03c23eedb8