并发编程

4.2、正确的中断线程

2020-09-01  本文已影响0人  liyc712

示例:

/**
 * 描述:注意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,程序运行结束
     *
     */
}
上一篇 下一篇

猜你喜欢

热点阅读