美文网首页并发编程
4.2、正确的中断线程

4.2、正确的中断线程

作者: liyc712 | 来源:发表于2020-09-01 11:50 被阅读0次
    • public static boolean interrupted()是静态方法:注意起作用的是是当前线程,和使用哪个线程实例没关系,并且会重置当前线程的中断状态
    • isInterrupted()是实例方法,是调用该方法的对象所表示的那个线程的isInterrupted(),不会重置当前线程的中断状态

    示例:

    /**
     * 描述:注意Thread.interrupted()方法的目标对象是“当前线程”,而不管本方法来自于哪个对象
     */
    public class RightWayInterrupted {
    
        public static void main(String[] args) throws InterruptedException {
    
            Thread threadOne = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (; ; ) {
                    }
                }
            });
    
            // 启动线程
            threadOne.start();
            //设置中断标志
            threadOne.interrupt();
            // 1.获取中断标志
            System.out.println("获取中断标志 threadOne.isInterrupted(): " + threadOne.isInterrupted());
            // 2.获取中断标志并重置
            System.out.println("获取中断标志并重置 threadOne.interrupted(): " + threadOne.interrupted());
            // 3.获取中断标志并重直
            System.out.println("获取中断标志并重直 Thread.interrupted(): " + Thread.interrupted());
            // 4.获取中断标志
            System.out.println("获取中断标志 threadOne.isInterrupted(): " + threadOne.isInterrupted());
            threadOne.join();
            System.out.println("Main thread is over.");
        }
    
        /**
         *注意Thread.interrupted()方法的目标对象是“当前线程”,而不管本方法来自于哪个对象的实例
         *
         *
         * 输出结果:
         *
         * 获取中断标志 threadOne.isInterrupted(): true
         * 获取中断标志并重置 threadOne.interrupted(): false
         * 获取中断标志并重直 Thread.interrupted(): false
         * 获取中断标志 threadOne.isInterrupted(): true
         *
         * 结果分析
         * 由于Thread.interrupted()方法的目标对象是“当前线程”,
         * 所以步骤2,和步骤3虽然调用了Thread.interrupted()但是他的的目标是当前线程,
         * 即使使用了threadOne的实例对象也并不会改变线程threadOne的中断标识
         *
         */
    }
    

    最佳实践1:

    catch了InterruptedExcetion之后的优先选择:在方法签名中抛出异常 那么在run()就会强制try/catch

    /**
     * 描述:最佳实践1:catch了InterruptedExcetion之后的优先选择:在方法签名中抛出异常 那么在run()就会强制try/catch
     */
    public class RightWayStopThreadInProd implements Runnable {
    
        @Override
        public void run() {
            while (true && !Thread.currentThread().isInterrupted()) {
                System.out.println("go");
                try {
                    throwInMethod();
                } catch (InterruptedException e) {
                    // 在InterruptedException异常中重新设置中断标识
                    Thread.currentThread().interrupt();
                    //保存日志、停止程序
                    System.out.println("保存日志");
                    e.printStackTrace();
                }
            }
        }
    
        private void throwInMethod() throws InterruptedException {
                Thread.sleep(2000);
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(new RightWayStopThreadInProd());
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        }
    
        /**
         *
         *最佳实践1:catch了InterruptedExcetion之后的优先选择:在方法签名中抛出异常 那么在run()就会强制try/catch
         *
         *输出结果
         * go
         * 保存日志
         * java.lang.InterruptedException: sleep interrupted
         *  at java.lang.Thread.sleep(Native Method)
         *  at com.liyc.concurrency.threadcoreknowledge.stopthreads.RightWayStopThreadInProd.throwInMethod(RightWayStopThreadInProd.java:26)
         *  at com.liyc.concurrency.threadcoreknowledge.stopthreads.RightWayStopThreadInProd.run(RightWayStopThreadInProd.java:14)
         *  at java.lang.Thread.run(Thread.java:748)
         *
         */
    }
    

    最佳实践2:

    在catch子语句中调用Thread.currentThread().interrupt()来恢复设置中断状态,以便于在后续的执行中,依然能够检查到刚才发生了中断 回到刚才RightWayStopThreadInProd补上中断,让它跳出

    /**
     * 描述:最佳实践2:在catch子语句中调用Thread.currentThread().interrupt()来恢复设置中断状态,以便于在后续的执行中,依然能够检查到刚才发生了中断
     * 回到刚才RightWayStopThreadInProd补上中断,让它跳出
     */
    public class RightWayStopThreadInProd2 implements Runnable {
    
        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("Interrupted,程序运行结束");
                    break;
                }
                reInterrupt();
            }
        }
    
        private void reInterrupt() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                //当捕获到了InterruptedException,系统会清空之前设置的interrupt中断标识
                // 此处在重新设置一次,以便于在后续的执行中,依然能够检查到刚才发生了中断
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(new RightWayStopThreadInProd2());
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        }
        /**
         *描述:最佳实践2:在catch子语句中调用Thread.currentThread().interrupt()来恢复设置中断状态,以便于在后续的执行中,依然能够检查到刚才发生了中断
         * 回到刚才RightWayStopThreadInProd补上中断,让它跳出
         *
         * java.lang.InterruptedException: sleep interrupted
         *  at java.lang.Thread.sleep(Native Method)
         *  at com.liyc.concurrency.threadcoreknowledge.stopthreads.RightWayStopThreadInProd2.reInterrupt(RightWayStopThreadInProd2.java:22)
         *  at com.liyc.concurrency.threadcoreknowledge.stopthreads.RightWayStopThreadInProd2.run(RightWayStopThreadInProd2.java:16)
         *  at java.lang.Thread.run(Thread.java:748)
         * Interrupted,程序运行结束
         *
         */
    }
    

    相关文章

      网友评论

        本文标题:4.2、正确的中断线程

        本文链接:https://www.haomeiwen.com/subject/kqfvsktx.html