How to properly interrupt a thread? Is your posture correct

Java’s logic to stop threads (coordination, notification)

In a Java program, if we want to stop a thread, we can stop it through the interrupt method. But when we call the interrupt method, it may not stop the thread immediately, but inform the thread that it needs to stop. After the thread receives the notification, it will judge whether it needs to stop according to its own situation. It may stop immediately, or it may stop after a period of execution, or it may not stop at all.

So why does Java choose this non-mandatory thread interruption? In fact, it is more for data security and to ensure the robustness of the program. Because we don’t know what the program is doing. If it is stopped rashly, it may cause confusion and incompleteness of data.

A simple example :

 public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {
            System.out.println("count: " + count++);
        }
    }

    public static void main(String[] args) throws Exception {
        _24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();
    }
}

This example is a simple case of interrupting a thread through interrupt. In the run method, the loop is performed by judging whether the current thread is interrupted and whether the count is greater than 2000. If the thread is interrupted, the loop is exited and the thread execution ends. This is the case when the thread is stopped normally.

Whether Sleep will receive the thread interrupt signal

 public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {
            try {
                System.out.println("count: " + count++);
                // 子线程睡眠
                Thread.sleep(1000 * 2);
                System.out.println("方法体:" + Thread.currentThread().isInterrupted());
            } catch (InterruptedException e) {
                System.out.println("异常:" + Thread.currentThread().isInterrupted());
                // 线程中断标志位被重置为false
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        _24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();
    }
}

If the main thread is interrupted by the interrupt method during sleep in the child thread, can the child thread still receive the interrupt signal. In fact, in this case, the thread can also receive the signal notification. At this time, an InterruptedException will be thrown, and the thread interrupt flag will be set to false.

After the exception is thrown, the thread flag is set to false, then the loop body can still be entered if the count is not false in the next loop. At this point the thread cannot be stopped.

Results of the:

Case scenario :

When running some background tasks through threads, if a thread interruption exception is encountered in the loop, we need to terminate the current task and tell the client which record the current task fails to execute. In this case, we can pass the exception. The method of interrupting again to stop the thread, and can return to the client which record of the current exception occurred. rather than continuing.

Solution

 public class _24_ThreadTest implements Runnable {

    @Override
    public void run() {
        int count = 0;
        while (!Thread.currentThread().isInterrupted() && count <= 2000) {
            try {
                System.out.println("count: " + count++);
                // 子线程睡眠
                Thread.sleep(1000 * 2);
                Thread.currentThread().interrupt();
                System.out.println("方法体:" + Thread.currentThread().isInterrupted());
            } catch (InterruptedException e) {
                // 再次中断
                Thread.currentThread().interrupt();
                System.out.println("异常:" + Thread.currentThread().isInterrupted());
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        _24_ThreadTest threadTest = new _24_ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        Thread.sleep(10);
        // 中断线程
        thread.interrupt();
    }
}

Now that we know that the thread interrupt flag will be reset to false after the thread interrupt exception occurs, then we can manually interrupt the current thread again in the exception, then we can completely stop the thread task.

Summarize

Above we briefly introduced how to stop the thread correctly. If you are asked this kind of question in the future interview, then you can answer the interviewer fluently.

When an exception is encountered in the run method, we cannot swallow it directly. We must deal with it. You can use simple logging or interrupt the thread. But just can’t do anything about it.

In fact, there are other methods to stop the thread, such as stop(), which have been abandoned. This forced stop may cause data security problems of the thread, so it is no longer recommended.