中断线程


前言

提示:线程的结束可以分为正常结束,和异常结束。结束线程有两种方式:1.是用stop方法,不过这个方法是强行结束正在运行的线程,会存在数据不一致的问题,已经废弃,2.是用interrupte status ,本文主要介绍2。


一、认识中断标志位

1. interrupted()

interrupt方法用于中断线程。调用该方法的线程的状态将被置为"中断"状态。

如何使用:

  1. 线程中断仅仅是改变线程的中断状态位,不会停止线程。
  2. 需要用户自己去监视线程的状态位并做出相应处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

对于2我们来说明下:

public class 中断线程 {

    public static void main(String[] args) throws InterruptedException {
        try {
            InterruptService interruptService = new InterruptService();
            Thread thread = new Thread(interruptService);
            thread.start();
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    private static class InterruptService implements Runnable {
        //如果使用Callable接口中call方法异常就会得以扩散
        @Override
        public void run() {
            try {
                System.out.println( "begin run" );
                //重要:无论是先中断还是先阻塞都能达到停止线程的目的,只要两者配置使用就可以到达效果
                // 这里的中断只是设置了中断标志位,而无法真正的中断线程。除非和以下三种方式结合
                /**
                 *  * <p> If this thread is blocked in an invocation of the {@link
                 *      * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
                 *      * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
                 *      * class, or of the {@link #join()}, {@link #join(long)}, {@link
                 *      * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
                 *      * methods of this class, then its interrupt status will be cleared and it
                 *      * will receive an {@link InterruptedException}.
                 *
                 *      这里说明了在经历阻塞方法时,中断状态就被清空了,同时还要抛出一个中断异常
                 */
                Thread.currentThread().interrupt();
                System.out.println(Thread.currentThread().isInterrupted());



                //方式一,线程进入sleep
                Thread.sleep( 10 );
                //方式二、join
//            Thread.currentThread().join();
                //方式三、wait
//            Thread.currentThread().wait();
                System.out.println( "begin end" );
            } catch (Exception e) {
                /**
                 * * Tests whether the current thread has been interrupted.  The
                 *      * <i>interrupted status</i> of the thread is cleared by this method.  In
                 *      * other words, if this method were to be called twice in succession, the
                 *      * second call would return false (unless the current thread were
                 *      * interrupted again, after the first call had cleared its interrupted
                 *      * status and before the second call had examined it).
                 */
                System.out.println(Thread.currentThread().isInterrupted());
                System.out.println(Thread.currentThread().isInterrupted());

                System.out.println("先interrupt再阻塞后终止了");
                e.printStackTrace();
            }
        }
    }
}

上面所示的也是一个当发生中断异常时,也就结束了线程的示例。我们来看下sleep方法:

/**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

我们看抛出异常时的javadoc,就可以发现,当前线程被中断时,就会清除当前状态标志位,然后报出异常,当然这里没有显示的写出检查线程状态标志位 的代码,这里是jvm去处理了。我们可以看AbstractQueuedSynchronizer的await方法,就显示的去检查了线程的中断状态。

2. interrupted() vs isInterrupted()

点进源码,我们发现都是调用了isInterrupted(boolean ClearInterrupted)。他们都是查看的方法,参数为true则是重置中断标志,否则只是查看并不重置(isInterrupted()是只查看)。

二、InterrupteException的处理

上面我们提到了中断标志位的设置和查看,还提到了阻塞方法(即会一直检查标志位,并会抛出中断异常的方法)会使线程真正的中断,那么下面我们就来说下,抛出异常后我们要怎么处理。

  1. 直接向上层抛出
  2. 捕获并做业务处理
  3. 线程的run方法中捕获后,应继续设置中断状态为true,以保留证据,使得其他地方可见
    详情参考

参考

参考:
方法阻塞和异常处理
中断方法对比

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值