Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

interrupt interrupted isInterrupted 方法对比、区别与联系 多线程中篇(八)

noteless 2019-02-16 09:20:00 阅读数:180 评论数:0 点赞数:0 收藏数:0

interrupt interrupted isInterrupted 是三个“长相”非常类似的方法。

本文将对这三个方法简单的对比下,首先了解下线程停止的方式

线程停止方式

在Java中如果想停止一个线程,有三种方法

  • 采用退出标志,使得run方法执行完之后线程自然终止
  • 使用stop强行终止线程,但该方法由于安全问题已经被deprecated
  • 使用中断机制

退出标志

public class T9 extendsThread {private booleanrunning;public void setRunning(booleanrunning) {this.running =running; } @Overridepublic voidrun() {while(running){ System.out.println("i am working ...."); } }public static voidmain(String[] args) { T9 myThread= newT9(); myThread.setRunning(true); myThread.start();try{ TimeUnit.MILLISECONDS.sleep(2); }catch(Exception e) { } myThread.setRunning(false); } }

运行几次,结果略有不同![image_5c64c4ae_2bf0](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093002208-1072132479.png)

stop 弃用

public class T9 extendsThread {private booleanrunning;public void setRunning(booleanrunning) {this.running =running; } @Overridepublic voidrun() {while(running) { System.out.println("i am working ...."); } }public static voidmain(String[] args) { T9 myThread= newT9(); myThread.setRunning(true); myThread.start();try{ TimeUnit.MILLISECONDS.sleep(2); }catch(Exception e) { } myThread.stop(); } }

中断机制

stop等方法已经弃用,退出标记不够灵活有时也有问题,所以目前最合适的解决方式是借助于中断机制

中断机制是一种处理逻辑,而不是说立即中断中断机制是一种“请求---处理”模型,是一种软中断,并不会因为中断的设置立即停止运行

中断机制的逻辑借助于“中断标志”,当请求一个线程中断时,可以通过设置目标线程的中断标志位进行操作简单的逻辑如下图所示:

![image_5c64c4ae_523](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093002897-2014014868.png)所以说,对于线程的停止的三种方式,中断机制是一种更好的方式,而且也是一种更加友好的方式。

public class T9 extendsThread {private booleanrunning;public void setRunning(booleanrunning) {this.running =running; } @Overridepublic voidrun() {while(running) { System.out.println("i am working ...."); } }public static voidmain(String[] args) { T9 myThread= newT9(); myThread.setRunning(true); myThread.start(); myThread.interrupt(); } }上面的代码中,尽管我们通过myThread.interrupt();设置了标志位,但是线程仍旧继续运行,完全并没有停止的意思

![image_5c64c4ae_46e8](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093003329-1872154004.png)public class T9 extendsThread {private booleanrunning;public void setRunning(booleanrunning) {this.running =running; } @Overridepublic voidrun() {while(running) {if(Thread.currentThread().isInterrupted()) {break; } System.out.println("i am working ...."); } }public static voidmain(String[] args) { T9 myThread= newT9(); myThread.setRunning(true); myThread.start();try{ TimeUnit.MILLISECONDS.sleep(2); }catch(Exception e) { } myThread.interrupt(); } }

上面代码中,在run方法中判断中断标志位,如果发现中断标志被置位,那么break,也就是跳出循环主函数中,线程启动后,主线程休眠2毫秒然后将myThread中断,程序运行一段时间后终止运行

![image_5c64c4ae_3b32](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093003708-1866238959.png)所以可以看得出来,借助于中断机制对一个线程进行处理,进行中断标志置位,并不会对线程的运行产生影响,到底有何影响,重点要看到底你面对中断标志位会做什么处理。

中断标志位

通过上面的分析,我们可以很清楚的看得出来,中断机制的核心就是借助于中断标志位

而 interrupt interrupted isInterrupted三个方法其实就是对于中断标志位的操作重新审视下方法,两个实例方法一个静态方法

![image_5c64c4ae_c76](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093004564-1722202604.png)API文档

public void interrupt()

中断一个线程(设置标志位)除非是当前线程正在中断自己(这在任何情况下都是允许的),否则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。

如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。

如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。如果以前的条件都没有保存,则该线程的中断状态将被设置。

中断一个不处于活动状态的线程不需要任何作用。抛出:

SecurityException - 如果当前线程无法修改该线程 注意:

如果不是线程自己在中断自己的话,会有安全管理器先进行校验,如果权限不够,将会抛出SecurityException如果位于特殊的等待状态,比如调用wait()、wait(long)或者join()或者sleep()等方法,中断标志位将会被清除,并且收到一个InterruptedException

前面说到中断标志被置位不影响线程的正常运行,但是这个InterruptedException又是什么意思?中断标志的确是不影响线程的运行,要看线程对于中断标志是如何进行处理的

但是如果处于等待的话,就会抛出异常 

简单说,当一个线程正常运行的时候,可以不用搭理中断标志位;但是如果比如在等人,在睡觉,一旦被中断就会被吵醒,吵醒了、不爽了、自然要发发牢骚,这个牢骚就是InterruptedException

public boolean isInterrupted()

测试线程是否已经中断线程的中断状态不受该方法的影响

A thread interruption ignored because a thread was not alive at the time of the interrupt will be reflected by this method returning false.

在中断发生时,如果一个线程并不是alive的,中断操作将会被忽略,也会通过这个方法返回false反映出来 

返回:如果该线程已经中断,则返回 true;否则返回 false。

如果一个线程根本都不是alive的,调用这个方法也是返回false![image_5c64c4ae_3d75](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093007168-934813423.png)public static boolean interrupted()

测试当前线程是否已经中断。线程的中断状态 由该方法清除。

换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。在中断发生时,如果一个线程并不是alive的,中断操作将会被忽略,也会通过这个方法返回false反映出来

A thread interruption ignored because a thread was not alive at the time of the interrupt will be reflected by this method returning false.返回:

如果当前线程已经中断,则返回 true;否则返回 false。

接下来看一个方法![image_5c64c4ae_6e8a](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093007617-1768792489.png)

测试线程是否被中断。中断标志位将会根据参数ClearInterrupted的值决定是否会被清除

这是一个实例方法,所以需要依赖于某个实例对象再仔细看看静态方法interrupted

![image_5c64c4ae_37c4](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093008731-898754577.png)内部借助于上面的那个私有方法

他的含义就是,测试当前线程是否被中断,并且清除中断标志位而对于实例方法isInterrupted,仍旧是借助于本地方法,测试某个线程是否被中断,但是并不会清除线程的中断标志

![image_5c64c4ae_c9c](https://img2018.cnblogs.com/blog/897393/201902/897393-20190214093009213-1411852515.png)

小结

三个方法全都是用来对线程中断标志进行操作的

public void interrupt()、public boolean isInterrupted()作为实例方法,是对指定线程的操作假设中断标志位interruptState

那么对于interrupt来说相当于set方法public void setInterruptState(booleaninterruptState) {this.interruptState =interruptState; }

对于isInterrupted来说,相当于get方法public booleanisInterruptState() {returninterruptState; }

而对于interrupted() 则是相当于getter  and  setter,并且,是针对于当前线程的

总结

对于三个方法interrupt interrupted isInterrupted,重点是要了解中断标志位

从getter和setter方法的角度理解的话,能够更好地理解,从方法名中也可以很好地看得出来 interrupt作为动词,所以是使之中断,自然是setter方法

而对于isInterrupted 典型的疑问句式,所以是对中断标志位的测试 是getter方法interrupted看起来就奇葩了一点,所以他是set和get ,并且是针对当前线程的

这样的话就不会混淆了,毕竟名字的确是有些接近原文地址:interrupt interrupted isInterrupted 方法对比、区别与联系 多线程中篇(八)

 

版权声明
本文为[noteless]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/noteless/p/10372826.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领