interrupt interrupted isInterrupted 是三个“长相”非常类似的方法。
本文将对这三个方法简单的对比下,首先了解下线程停止的方式

线程停止方式

在Java中如果想停止一个线程,有三种方法
  • 采用退出标志,使得run方法执行完之后线程自然终止
  • 使用stop强行终止线程,但该方法由于安全问题已经被deprecated
  • 使用中断机制

退出标志

public class T9 extends Thread {
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (running){
System.out.println("i am working ....");
}
}
public static void main(String[] args) {
T9 myThread = new T9();
myThread.setRunning(true);
myThread.start();
try {
TimeUnit.MILLISECONDS.sleep(2);
} catch (Exception e) {
}
myThread.setRunning(false);
}
}
运行几次,结果略有不同

stop 弃用

public class T9 extends Thread {
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (running) {
System.out.println("i am working ....");
}
}
public static void main(String[] args) {
T9 myThread = new T9();
myThread.setRunning(true);
myThread.start();
try {
TimeUnit.MILLISECONDS.sleep(2);
} catch (Exception e) {
}
myThread.stop();
}
}

中断机制

stop等方法已经弃用,退出标记不够灵活有时也有问题,所以目前最合适的解决方式是借助于中断机制
中断机制是一种处理逻辑,而不是说立即中断
中断机制是一种“请求---处理”模型,是一种软中断,并不会因为中断的设置立即停止运行
中断机制的逻辑借助于“中断标志”,当请求一个线程中断时,可以通过设置目标线程的中断标志位进行操作
简单的逻辑如下图所示:
所以说,对于线程的停止的三种方式,中断机制是一种更好的方式,而且也是一种更加友好的方式。
public class T9 extends Thread {
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (running) {
System.out.println("i am working ....");
}
}
public static void main(String[] args) {
T9 myThread = new T9();
myThread.setRunning(true);
myThread.start();
myThread.interrupt();
}
}
上面的代码中,尽管我们通过myThread.interrupt();设置了标志位,但是线程仍旧继续运行,完全并没有停止的意思
public class T9 extends Thread {
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (running) {
if (Thread.currentThread().isInterrupted()) {
break;
}
System.out.println("i am working ....");
}
}
public static void main(String[] args) {
T9 myThread = new T9();
myThread.setRunning(true);
myThread.start();
try {
TimeUnit.MILLISECONDS.sleep(2);
} catch (Exception e) {
}
myThread.interrupt();
}
}
上面代码中,在run方法中判断中断标志位,如果发现中断标志被置位,那么break,也就是跳出循环
主函数中,线程启动后,主线程休眠2毫秒然后将myThread中断,程序运行一段时间后终止运行
所以可以看得出来,借助于中断机制对一个线程进行处理,进行中断标志置位,并不会对线程的运行产生影响,到底有何影响,重点要看到底你面对中断标志位会做什么处理。

中断标志位

通过上面的分析,我们可以很清楚的看得出来,中断机制的核心就是借助于中断标志位
而 interrupt interrupted isInterrupted三个方法其实就是对于中断标志位的操作
重新审视下方法,两个实例方法一个静态方法
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
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。
接下来看一个方法
测试线程是否被中断。
中断标志位将会根据参数ClearInterrupted的值决定是否会被清除
这是一个实例方法,所以需要依赖于某个实例对象
再仔细看看静态方法interrupted
内部借助于上面的那个私有方法
他的含义就是,测试当前线程是否被中断,并且清除中断标志位
而对于实例方法isInterrupted,仍旧是借助于本地方法,测试某个线程是否被中断,但是并不会清除线程的中断标志

小结

三个方法全都是用来对线程中断标志进行操作的
public void interrupt()、public boolean isInterrupted()作为实例方法,是对指定线程的操作
假设中断标志位interruptState
那么对于interrupt来说相当于set方法
  public void setInterruptState(boolean interruptState) {
this.interruptState = interruptState;
}
对于isInterrupted来说,相当于get方法
  public boolean isInterruptState() {
return interruptState;
}
而对于interrupted() 则是相当于getter  and  setter,并且,是针对于当前线程的

总结

对于三个方法interrupt interrupted isInterrupted,重点是要了解中断标志位
从getter和setter方法的角度理解的话,能够更好地理解,从方法名中也可以很好地看得出来 
interrupt作为动词,所以是使之中断,自然是setter方法
而对于isInterrupted 典型的疑问句式,所以是对中断标志位的测试 是getter方法
interrupted看起来就奇葩了一点,所以他是set和get ,并且是针对当前线程的
这样的话就不会混淆了,毕竟名字的确是有些接近

interrupt interrupted isInterrupted 方法对比、区别与联系 多线程中篇(八)的更多相关文章

  1. java多线程 interrupt(), interrupted(), isInterrupted()方法区别

    interrupt()方法: 作用是中断线程. 本线程中断自身是被允许的,且"中断标记"设置为true 其它线程调用本线程的interrupt()方法时,会通过checkAcces ...

  2. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

  3. 十四 关于interrupt, interrupted, isInterrupted

    1 判断线程是否是停止状态? interrupt() : interrupt方法用于中断线程.调用该方法的线程的状态为将被置为"中断"状态. 注意:线程中断仅仅是置线程的中断状态位 ...

  4. Java 中 interrupted 和 isInterrupted 方法的区别?

    interrupt interrupt 方法用于中断线程.调用该方法的线程的状态为将被置为"中断"状态. 注意:线程中断仅仅是置线程的中断状态位,不会停止线程.需要用户自己去监 视 ...

  5. Thread类的interrupted方法和isInterrupted方法的区别

    如下所示,interrupted()会改变线程的中断状态(清除),而isInterrupted()不影响线程的中断状态   /** * Tests whether the current thread ...

  6. interrupt(),interrupted() 和 isInterrupted() 的区别

    1. 结论先行 interrupt():将调用该方法的对象所表示的线程标记一个停止标记,并不是真的停止该线程. interrupted():获取当前线程的中断状态,并且会清除线程的状态标记.是一个是静 ...

  7. java中interrupt,interrupted和isInterrupted的区别

    文章目录 isInterrupted interrupted interrupt java中interrupt,interrupted和isInterrupted的区别 前面的文章我们讲到了调用int ...

  8. interrupt ,interrupted 和 isInterrupted

    1.interrupt  interrupt方法用于中断线程.调用该方法的线程的状态为将被置为"中断"状态. 注意:线程中断仅仅是置线程的中断状态位,不会停止线程.需要用户自己去监 ...

  9. Java线程状态及 wait、sleep、join、interrupt、yield等的区别

    Java中的线程状态(详见Java线程状态及转换-MarchOn): wait:Object类的实例方法,释放CPU执行权,进入等待状态,直到  被中断.被拥有该对象锁的线程唤醒(notify或not ...

随机推荐

  1. BZOJ_1180_[CROATIAN2009]OTOCI_LCT

    BZOJ_1180_[CROATIAN2009]OTOCI_LCT Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作:  1.bridge A ...

  2. 终于将SAP系统完全配置通过了

    花了近10天的时间,每天晚上加班加点,终于将SAP S4 1610 IDES系统从零到有,从头到尾配置一遍.目前只启用了一家模拟公司,从基础数据的设置,到销售订单开立(含按单按库需求),跑MRP需求, ...

  3. C# - 如何让类型可以比较

    IComparable<T> .NET 里,IComparable<T>是用来作比较的最常用接口. 如果某个类型的实例需要与该类型的其它实例进行比较或者排序的话,那么该类型就可 ...

  4. PCA与LDA介绍

    PCA(主成分分析) PCA是一种无监督降维方式,它将数据投影到一组互相正交的loading vectors(principal axes)之上,并保证投影后的点在新的坐标轴上的方差最大 记数据集\( ...

  5. 4K视频在线看,网速跟不上怎么办?

    灿烂的阳光,温柔的风,二狗子一打开窗,觉得春天到了. “天气这么好,宅家玩电脑.”二狗子说着,点开了爱奇怪 App,最近一期的版本更新提到了支持 4K 视频播放,这是二狗子等了好久的功能. “今天我就 ...

  6. 【重学计算机】操作系统D6章:并发程序设计

    1. 并发程序的基本概念 程序顺序性 内部顺序性:CPU严格按照顺序执行指令 外部顺序性:程序员设计程序时往往用顺序设计的思想 顺序程序特性 程序执行的顺序性 计算环境的封闭性: 程序执行时犹如独占资 ...

  7. .NET Core微服务系列基础文章索引(目录导航Final版)

    一.为啥要总结和收集这个系列? 今年从原来的Team里面被抽出来加入了新的Team,开始做Java微服务的开发工作,接触了Spring Boot, Spring Cloud等技术栈,对微服务这种架构有 ...

  8. 约定Jenkins构建脚本

    对于Jenkins的使用,我感觉只用到其中一小部分功能,但也就是这一小部分功能,也推动了整个CI/CD的过程,Jenkins的使用方式有很多中,可能我用到的只是其中一种,但是已经满足我的需求,便不再贪 ...

  9. .NET Core:依赖注入

      在Startup的ConfigureServices方法中加入需要依赖注入的东西. 每次从容器 中获取的时候都是一个新的实例:services.AddTransient<ITransient ...

  10. Percona XtraBackup 8.0, 安装与测试

    Percona XtraBackup 8.0 是Percona XtraBackup新推出了一个针对MySQL8.0的版本,主要是MySQL8.0在Redo 和 数据库字典方面有了新的改进. Xtra ...