Java线程之中断(InterruptedException处理)

线程启动是为了去执行一些代码,大家有没有想过,要怎么停止一个线程呢?线程执行完任务会自动停止的,这个大家都知道,可是,要想中途停止一个线程,尤其是阻塞中的线程,要怎么做呢?Thread stop方法官方已经废弃了,这种方式太暴力,会导致数据不一致问题,而且线程也没有必要说停止就要立马停止,所以Thread搞了一个中断机制的概念。

中断就是给线程设置一个标示,线程在执行过程(尤其是循环执行任务的时候)中可以查询这个标示来决定要怎么做,可以继续执行也可以停止执行退出线程。而且对于有些阻塞中的线程,会响应中断的,比如Thread.sleep、Thread.join、Object.wait等阻塞方法会导致线程阻塞,而且能响应中断,响应中断的方式是抛出InterruptedException,这样调用阻塞方法的地方就可以捕获这个异常进行处理,决定要不要退出线程。我估计内部也是查询了中断标示,如果线程被中断了就throw InterruptedException,具体还没研究到这块。需要说明的是,不是任何阻塞线程都可以响应中断的,比如同步(synchronized)导致的阻塞,是不能响应中断的;输入和输出流类会阻塞等待I/O完成,也不响应中断的。

说到对InterruptedException的处理就有学问了,总体上有两个原则:

(1)在一个方法中能抛出去InterruptedException的时候,一定要抛出去,让调用者可以感知到中断,也就是说让中断可以传播到调用者。可以不捕获InterruptedException,直接传播给调用者;也可以捕获InterruptedException执行一些清理工作再重新抛出InterruptedException。

(2)在一个方法中不能抛出InterruptedException的时候,主要是指Runnable的run方法,也不要生吞(swallow)中断。阻塞方法在响应中断抛出InterruptedException的时候会清除中断标示(难道是调用Thread.interrupted()查询中断标示的??),在run方法中捕获了InterruptedException,而又不能进行抛出的话,调用者是不知道线程被中断了呀,因为中断标示已经被清除了。正确的做法是,捕获InterruptedException再次中断线程恢复中断状态。除非明确知道要退出线程了,可以生吞中断。

 

说一些和线程相关异常的话题,Thread实现了Runnable接口,Thread的run方法也是不能throws异常的,当然这里说的异常是非运行时异常,运行是异常是不用throws的,所以需要在Thread的run中捕获异常进行处理,IDE也会提醒的,要不然编译不过。InterruptedException就属于这类异常,需要在Thread run中捕获处理的,而上面说的不要swallow中断,指的的普通任务Runnable中的run方法,调用者还可能需要感知中断,所以得让中断信息传递,但是到了Thread的run方法时,线程明确就要退出了,可以生吞中断了。非运行时异常是不会从线程中逃逸的,因为不捕获都编译不过,但是运行时异常是可以的。由于线程的本质特性,使得你不能捕获从线程中逃逸的异常。也就是说,异常是不能跨线程捕获的。比如A线程的run方法中htrow new RuntimeException(),在主线程启动A线程,同时try catch是无效的。Thread提供了未捕获的异常处理器机制unCaughtExceptionHandler,其实还是线程自己捕获处理了异常,只不过是集中处理了。具体可以看《Java编程思想》第4版21.2.14

 

处理 InterruptedException

JAVA多线程之中断机制(如何处理中断?)

再探java基础——throw与throws

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值