Future.get()抛出ExecutionException或InterruptedException?

ExecutionException和InterruptedException是两个非常不同的事情。 ExecutionException封装了正在执行的线程抛出的任何异常,所以如果线程是做某种IO导致抛出IOException异常的,那么它会被包装在一个ExecutionException中并被重新抛出。 InterruptedException不是任何出错的迹象。在那里给你一种让你的线程知道什么时候停止的方法,以便他们完成当前的工作并优雅地退出。假设我希望我的应用程序停止运行,但我不希望我的线程放弃他们正在做的事情(这是如果我让它们守护进程线程会发生什么)。因此,当应用程序正在关闭时,我的代码会在这些线程上调用中断方法,这些线程会在中断标志上设置中断标志,并在下一次线程处于等待或休眠状态时检查中断标志并引发InterruptedException,我可以使用它从线程参与的无限循环处理/休眠逻辑中解脱出来(如果线程不等待或休眠,它可以定期检查中断标志。)因此,它是一个用于更改逻辑流程的异常实例。记录它的唯一原因是在一个示例程序中向您展示发生了什么,或者如果您正在调试中断逻辑无法正常工作的问题。

每个线程都拥有一个flag,标志着这个线程的中断位。如果一个线程A想让线程B退出,则A将B的中断位(interrupt flag)置为true,我们说“线程A向线程B发了中断信号”。此时如果B检查到了中断位为true,说明有线程想让它中断。如果B愿意的话,可以自愿地中断自己的线程。线程B检查自己的interrupt状态为true,并自愿地退出线程,是Java中唯一的一个线程让另一个线程终止的方法!
(为什么要设计成这样?
因为服务或线程不能被立即停止,立即停止会使共享的数据结构不一致,相反,应该在停止前做一些清理工作,然后再结束。所以说,不能你让我停我就停,我自己执行的任务,我比你更能清楚在停止前如何进行清理工作。因此,最终的设计就变成了:线程A给B发interrupt信号,B收到信号后,自己决定先做些什么,然后再退出。
这是一种协作机制,需要B配合。)

因此当执行很耗时的操作时,需要经常check interrupt的状态,并且一旦发现为true,就应该立即退出,这样才能及时取消那些非常耗时的操作。

在Thread中,有一些耗时操作,比如sleep()、join()、wait()等,都会在执行的时候check interrupt的状态,一旦检测到为true,立刻抛出InterruptedException。
Java中凡是抛出InterruptedException的方法(再加上Thread.interrupted()),都会在抛异常的时候,将interrupt flag重新置为false。
这也就是说,当一个线程B被中断的时候(比如正在sleep()),它会结束sleep状态,抛出InterruptedException,并将interrupt flag置为false。这也就意味着,此时再去检查线程B的interrupt flag的状态,它是false,不能证明它被中断了,现在唯一能证明当前线程B被中断的证据就是我们现在catch到的InterruptedException。

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值