interrupt interrupt and stop the thread

Thread a total of six in the state, namely:

New、Runnable、Blocked、Waiting、Timed Wating、Terminated

When analyzing the following methods when Runnable's run while loop, how to stop the execution thread while circulating in the external thread.

Look at the piece of code

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                int num = 0;
                while (num < Integer.MAX_VALUE){
                    System.out.println(Thread.currentThread().getName() + "正在执行");
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        // 执行t0.interrupt(),但是t0仍会继续运行
        t0.interrupt();
    }

We can see interrupt () did not allow the thread to stop running.

Role interrput () is the thread's interrupt status is set to true, not to say that after the implementation of t0.interrupt (), t0 thread enters Terminated (terminated state).

In two cases, the thread will enter the Terminated state:

    1, run run method ends.

    2, run method throws an exception.

Since interrupt thread interrupt flag is set to true, it will determine the condition of the while loop into judgment t0 interrupt status of the interrupt status to enter the while loop is false, exit the while loop is true, when the end of the run method runs, the thread becomes Terminated for the state of.

By Thread.currentThread (). IsInterrupted () can obtain interrupt state of the thread

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                // 当前线程的中断状态为true则退出while循环
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println(Thread.currentThread().getName() + "正在执行");
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        // 执行t0.interrupt(),t0的中断状态变为true
        t0.interrupt();
    }

Run the above code, the thread really stopped.

But using isInterrupted () to get the thread's interrupt status need to be careful when thread t0 throw InterruptedException, JVM will interrupt status is set to false t0 of.

Look at the following code

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    try {
                        System.out.println(Thread.currentThread().getName() + "正在执行");

                        // 在线程中加入sleep()这种可以响应中断的代码,并在while循环中把异常捕获
                        TimeUnit.MILLISECONDS.sleep(1);
                    }catch (InterruptedException e){
                        // 发生InterruptedException之后,线程的中断状态会被变成false
                        e.printStackTrace();
                    }
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        t0.interrupt();
    }

The code above will run forever, because then InterruptedException occurs, the thread interrupt status becomes false. The right way should be this: After the capture InterruptedException, will no longer execute the while loop in the run method.

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (!Thread.currentThread().isInterrupted()){
                        System.out.println(Thread.currentThread().getName() + "正在执行");
                        // 在线程中加入sleep()这种可以响应中断的代码
                        TimeUnit.MILLISECONDS.sleep(1);
                    }
                // 将捕获异常的代码放到while循环之外,捕获异常之后不再有循环代码
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        t0.interrupt();
    }

The above code will not be running, that thread will terminate t0.

When we catch the InterruptedException must think JVM thread's interrupt status is automatically set to false in the run method.

Another way is to use a modified volatile boolean variable to stop while, but this approach also has the bug, do not immediately stop the thread.

    // 停止生产标识
    public static volatile boolean stopProduce = false;

    public static void main(String[] args) throws Exception{
        // 资源队列,用于公共存储资源
        LinkedBlockingQueue lbq = new LinkedBlockingQueue(3);

        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                try {
                    while (i<Integer.MAX_VALUE && !stopProduce){
                        System.out.println("生产 "+i);
                        /**
                         * 当LinkedBlockingQueue队列满了,put方法会将线程设置为WAIT状态
                         * 若没有消费者消费LinkedBlockingQueue中的资源,线程会一直在这里等待,没法运行while判断
                         */
                        lbq.put(i);
                        i++;
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t0.start();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (new Random().nextInt(100)>5){
                        // 消费资源
                        System.out.println("消费 "+lbq.take());
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t1.start();

        TimeUnit.MILLISECONDS.sleep(10);

        // 设置停止生产标识为true,但是t0立刻没有停止,还处于WAIT状态
        stopProduce =true;

        // 消费一个LinkedBlockingQueue的资源后,t0从WAIT状态变为RUNNABLE,执行while判断后退出循环,线程结束
        //lbq.take();
    }

 

 

 

 

Published 51 original articles · won praise 14 · views 40000 +

Guess you like

Origin blog.csdn.net/u010606397/article/details/103891954