Mason talk about the basics of concurrent programming: thread interruption and termination

Mason talk about the basics of concurrent programming: thread interruption and termination

Original: www.spring4all.com

1 thread interrupt

1.1 What is thread interruption?

Thread interruption is a flag attribute of the thread. Rather than terminating the thread, it has nothing to do with the state of the thread. Thread interrupts the process represents a running thread, the thread is called by another thread interrupt()method, so that the thread interrupt flag property changes.

Under deeper thinking, thread interruption does not interrupt the thread, but is used to notify the thread that it should be interrupted. Specifically, it is a flag bit attribute. Whether the thread's life cycle ends or continues to run is handled by the thread itself according to the flag bit attribute.

1.2 Thread interrupt operation

The calling thread interrupt()method, there will be different results depending on the thread state.

Create a new InterruptedThread object below, the code is as follows:

/**
 *   true
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018 02 23 19:03:02
 */
public class InterruptedThread implements Runnable {

    @Override// 
    public void run() {
       //  run
        while (true) {
        }
    }

    public static void main(String[] args) throws Exception {

        Thread interruptedThread = new Thread(new InterruptedThread(), "InterruptedThread");
        interruptedThread.start();

        TimeUnit.SECONDS.sleep(2);

        interruptedThread.interrupt();
        System.out.println("InterruptedThread interrupted is " + interruptedThread.isInterrupted());

        TimeUnit.SECONDS.sleep(2);
    }
}
 

Run the main function, the results are as follows:

InterruptedThread interrupted is true
 

Detailed code:

  • The thread is always running, not stopped or blocked, etc.
  • Call a interrupt()method, interrupt status is set to true, but does not affect the continued operation of the thread

In another case, create a new InterruptedException object, the code is as follows:

/**
 *   InterruptedException   false
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018 02 23 19:03:02
 */
public class InterruptedException implements Runnable {

    @Override// 
    public void run() {
       //  sleep
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (java.lang.InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {

        Thread interruptedThread = new Thread(new InterruptedException(), "InterruptedThread");
        interruptedThread.start();

        TimeUnit.SECONDS.sleep(2);

       // sleep wait join   InterruptedException
       //  InterruptedException  JVM   false
        interruptedThread.interrupt();
        System.out.println("InterruptedThread interrupted is " + interruptedThread.isInterrupted());
        TimeUnit.SECONDS.sleep(2);
    }
}
 

Run the main function, the results are as follows:

InterruptedThread interrupted is false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
 

Detailed code:

  • Interrupting a thread in a blocked state (sleep, wait, join, etc.) will throw an exception InterruptedException
  • Before throwing the exception InterruptedException, the JVM will first reset the interrupted state to the default state false

Summary thread interruption:

  • Thread interruption, not stopping the thread, but just the flag attribute of a thread
  • If the thread state is blocked (sleep, wait, join, etc.), the thread state exits the blocked state, throws an exception InterruptedException, and resets the interrupted state to the default state false
  • If the thread status is running, the thread status does not change, continue to run, and the interrupt status is set to true

Code: github.com/JeffLi1993/...

2 thread termination

For example, it is definitely not correct to forcibly close the program in IDEA, stop the program immediately, and not release resources for the program. A similar problem exists with thread termination, so how to terminate the thread needs to be considered?

Talking about thread interruption above, you can use the thread interrupt flag bit attribute to safely terminate the thread. Similarly, you can also use the boolean variable to control whether the thread needs to be terminated.

New, the code is as follows:

/**
 *  
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018 02 23 19:03:02
 */
public class ThreadSafeStop {

    public static void main(String[] args) throws Exception {
        Runner one = new Runner();
        Thread countThread = new Thread(one, "CountThread");
        countThread.start();
       //  1   CountThread  
        TimeUnit.SECONDS.sleep(1);
        countThread.interrupt();

        Runner two = new Runner();
        countThread = new Thread(two,"CountThread");
        countThread.start();
       //  1  
        TimeUnit.SECONDS.sleep(1);
        two.stopSafely();
    }

    private static class Runner implements Runnable {

        private long i;

       // 
        private volatile boolean on = true;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
               // 
                i++;
            }
            System.out.println("Count i = " + i);
        }

        public void stopSafely() {
            on = false;
        }
    }
}
 

As seen from the above code, via while (on && !Thread.currentThread().isInterrupted())achieved whether the thread out of the execution logic, and termination code. But the question point came, why need onand isInterrupted()two together? Isn't it enough to use one of these methods? The answer is below

  • Thread member variables onby modifying the volatile keyword, visible, in order to achieve terminate the thread between the thread reach. But when the thread state is blocked (sleep, wait, join, etc.), the member variable operation is also blocked, and the thread cannot be terminated safely.
  • To deal with the above problems, introduced isInterrupted();only to solve thread safety terminated under the blocked state.
  • Is the combination of the two really okay? No, if it is network io blocking, for example, a websocket has been waiting for a response, then use the underlying close directly.

3 summary

Many friends have introduced that if you use the Spring stack to develop threads or thread pools, try to use the thread operations provided by the framework and the termination provided by the framework.

Source: "The Art of Java Concurrent Programming"