您的位置:首页 > 其它

线程中断的方式(interrupt详解)

2020-07-14 06:31 369 查看

1.线程中断的方式总结?

1.1 正常退出:在线程start()开启之后,当线程执行完run()或call()方法之后,此时,该线程会正常退出。
1.2 stop强制退出:在Thread类中,可以发现其中的stop()方法上加有@Deprecated注解,表示此方法已废弃、暂时可用,但以后此类或方法都不会再更新、后期可能会删除,建议后来人不要调用此方法。其主要原因是线程会立即停止,而且线程拥有的资源不会释放,例如锁;同类似的suspend()和resume()方法,也会导致资源得不到及时释放。造成死锁情况。
1.3 interrupt()抛出异常:在线程中调用interrupt()方法之后,会告知当前线程,中断标识已设置为true,至于线程是否会中断,则由线程本身去决定,此时线程可以通过调用sleep(),wait(),join()方法去阻塞线程;通过Thread源码可以得知,这三处方法都会抛出一个InterruptedException异常(线程中断异常),调用方法前都会去校验中断标识是否被中断,如果isInterrupted()返回值为true,则会抛出异常,并且此时该值会被重新设置为false。

2.interrupt用法扩展?

实际应用中的作用
1.[可以使线程继续执行],那就是在catch语句中招待醒来后的逻辑,或由catch语句转回正常的逻辑。总之它是从wait,sleep,join的暂停状态活过来了。
2.[可以直接停止线程的运行],当然在catch中什么也不处理,或return,那么就完成了当前线程的使命,可以使在上面"暂停"的状态中立即真正的"停止"。
  
注意点
1.通俗点来说,interrupt的作用并不是中断正在运行中的线程,而是类似于去监视线程的中断状态,当线程被阻塞时,通过异常去处理线程的阻塞状态,可以看作是一个中断的监听器;
2.sleep(),wait(),join()三个方法在被调用时,会不断去检查线程的中断状态;如果发现有线程被中断,则会抛出中断异常,实际上就是这个线程不需再等待了,相当于是唤醒该线程;
3.与wait()一起使用:被notify/All唤醒的线程会继续执行wait下面的语句,而在wait中被中断的线程则将控制权交给了catch语句.一些正常的逻辑要被放到catch中来运行。但有时这是唯一手段,比如一个线程a在某一对象b的wait中等待唤醒,其它线程必须获取到对象b的监视锁才能调用b.notify()[All],否则你就无法唤醒线程a,但在任何线程中可以无条件地调用a.interrupt();来达到这个目的.只是唤醒后的逻辑你要放在catch中,当然同notify/All一样,继续执行a线程的条件还是要等拿到b对象的监视锁。
4.与sleep(join)一起使用:对于sleep中的线程,如果你调用了Thread。sleep(一年);现在你后悔了,想让它早些醒过来,调用interrupt()方法就是唯一手段,只有改变它的中断状态,让它从sleep中将控制权转到处理异常的catch语句中,然后再由catch中的处理转换到正常的逻辑。同样,地于join中的线程你也可以这样处理;
5.该三个线程的阻塞方法与interrupt()执行方法的顺序无关,不论是先执行sleep后执行interrupt,还是先执行interrupt后执行sleep,线程都会由睡眠状态被唤醒;
6.interrupt方法在线程启动前,和结束后执行都是无效的,不会产生任何作用。

3.sleep等方法为什么要设计成抛出一个中断异常而且重置中断状态?

存在的问题:我们看过Thread的源码,可以知道stop等方法都是被废弃,jdk不建议使用的,原因就在于stop暴力停止后,可能一些资源得不到及时释放,例如锁资源,导致线程产生死锁的情况;同理,如果jdk不抛出异常,在线程调用interrupt后,一旦线程进入阻塞状态,立马中断线程,也会发生和stop同样的问题。而且开发人员也无法手动去处理该问题。
设计的好处:在sleep方法抛出异常后,开发人员可以释放线程所拥有的的资源,并且此时线程的中断状态为false,此时是否中断则由开发人员自己去控制。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: