java中interrupt,interrupted和isInterrupted的区别

前面的文章我们讲到了调用interrupt()来停止一个Thread,本文将会详细讲解java中三个非常相似的方法interrupt,interrupted和isInterrupted。

isInterrupted

首先看下最简单的isInterrupted方法。isInterrupted是Thread类中的一个实例方法:

    public boolean isInterrupted() {
return isInterrupted(false);
}

通过调用isInterrupted()可以判断实例线程是否被中断。

它的内部调用了isInterrupted(false)方法:

  /**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);

这个方法是个native方法,接收一个是否清除Interrupted标志位的参数。

我们可以看到isInterrupted()传入的参数是false,这就表示isInterrupted()只会判断是否被中断,而不会清除中断状态。

interrupted

interrupted是Thread中的一个类方法:

 public static boolean interrupted() {
return currentThread().isInterrupted(true);
}

我们可以看到,interrupted()也调用了isInterrupted(true)方法,不过它传递的参数是true,表示将会清除中断标志位。

注意,因为interrupted()是一个类方法,调用isInterrupted(true)判断的是当前线程是否被中断。注意这里currentThread()的使用。

interrupt

前面两个是判断是否中断的方法,而interrupt()就是真正触发中断的方法。

我们先看下interrupt的定义:

    public void interrupt() {
if (this != Thread.currentThread())
checkAccess(); synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}

从定义我们可以看到interrupt()是一个实例方法。

它的工作要点有下面4点:

  1. 如果当前线程实例在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法,或者在该实例中调用了Thread.sleep(long)或Thread.sleep(long,int)方法,并且正在阻塞状态中时,则其中断状态将被清除,并将收到InterruptedException。

  2. 如果此线程在InterruptibleChannel上的I / O操作中处于被阻塞状态,则该channel将被关闭,该线程的中断状态将被设置为true,并且该线程将收到java.nio.channels.ClosedByInterruptException异常。

  3. 如果此线程在java.nio.channels.Selector中处于被被阻塞状态,则将设置该线程的中断状态为true,并且它将立即从select操作中返回。

  4. 如果上面的情况都不成立,则设置中断状态为true。

我们来举个例子:

@Slf4j
public class InterruptThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
log.info("i= {}", (i+1));
log.info("call inside thread.interrupted(): {}", Thread.interrupted());
}
} @Test
public void testInterrupt(){
InterruptThread thread=new InterruptThread();
thread.start();
thread.interrupt();
//test isInterrupted
log.info("first call isInterrupted(): {}", thread.isInterrupted());
log.info("second call isInterrupted(): {}", thread.isInterrupted()); //test interrupted()
log.info("first call outside thread.interrupted(): {}", Thread.interrupted());
log.info("second call outside thread.interrupted() {}:", Thread.interrupted());
log.info("thread is alive : {}",thread.isAlive() );
}
}

输出结果如下:

13:07:17.804 [main] INFO com.flydean.InterruptThread - first call isInterrupted(): true
13:07:17.808 [main] INFO com.flydean.InterruptThread - second call isInterrupted(): true 13:07:17.808 [Thread-1] INFO com.flydean.InterruptThread - call inside thread.interrupted(): true
13:07:17.808 [Thread-1] INFO com.flydean.InterruptThread - call inside thread.interrupted(): false 13:07:17.808 [main] INFO com.flydean.InterruptThread - first call outside thread.interrupted(): false
13:07:17.809 [main] INFO com.flydean.InterruptThread - second call outside thread.interrupted() false

上面的例子中,两次调用thread.isInterrupted()的值都是true。

在线程内部调用Thread.interrupted(), 只有第一次返回的是ture,后面返回的都是false,这表明第一次被重置了。

在线程外部,因为并没有中断外部线程,所以返回的值一直都是false。

本文的例子参考https://github.com/ddean2009/learn-java-concurrency/tree/master/interrupt

更多教程请参考 flydean的博客

java中interrupt,interrupted和isInterrupted的区别的更多相关文章

  1. 【JAVA多线程】interrupted() 和 isInterrupted() 的区别

    Thread 类中提供了两种方法用来判断线程的状态是不是停止的.就是我们今天的两位主人公 interrupted() 和 isInterrupted() . interrupted() 官方解释:测试 ...

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

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

  3. Java中wait和sleep方法的区别

    1.两者的区别 这两个方法来自不同的类分别是Thread和Object 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁). wait ...

  4. 转 Java中wait和sleep方法的区别

    1.两者的区别 这两个方法来自不同的类分别是Thread和Object 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁). wait ...

  5. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  6. java中的sleep()和wait()的区别

    对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监 ...

  7. java中的this与super的区别

    java中的this与super的区别 1. 子类的构造函数如果要引用super的话,必须把super放在函数的首位 代码如下: class Base { Base() { System.out.pr ...

  8. JAVA中extends 与implements有啥区别?

    JAVA中extends 与implements有啥区别?1. 在类的声明中,通过关键字extends来创建一个类的子类.一个类通过关键字implements声明自己使用一个或者多个接口.extend ...

  9. JAVA中String = null 与 String = "" 的区别

    JAVA中String = null 与 String = ""的区别 笔者今天在Debug的时候发现的NPE(NullPointerException),辛辛苦苦地调试了半天,终 ...

随机推荐

  1. iOS开发|从小公司到进大厂,我的进阶学习之旅!

    iOS高级进发 OC源码下载地址 苹果开发文档 如何阅读苹果开发文档 GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍 源码地址:http://www.gnustep.o ...

  2. stm32:实现呼吸灯

    1.main.c #include "sys.h" #include "delay.h" #include "key.h" #define ...

  3. 《Three.js 入门指南》2- 照相机

    2.1 什么是照相机 我们使用Three.js创建的场景是三维的,而通常情况下显示屏是二维的,那么三维的场景如何显示到二维的显示屏上呢?照相机就是这样一个抽象,它定义了三维空间到二维屏幕的投影方式,用 ...

  4. java 根据图片文字动态生成图片

    今天在做热敏打印机打印二维码,并有文字描述,想到的简单的方法就是根据热敏打印机的纸张宽度和高度,生成对应的图片,如下: package com.orisdom.utils; import lombok ...

  5. JavaScript RegExp.​$1...$9 属性详解

    RegExp.$1...$9属性用于返回正则表达式模式中某个子表达式匹配的文本. 正则表达式中每个小括号内的部分表达式就是一个子表达式. 该属性是RegExp全局对象的一个只读属性,所有主流浏览器均支 ...

  6. Java进行二元操作类型转换

    当对两个数值进行二元操作时,先要将两个操作数转换为同一种类型,然后再进行计算. 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型. 否则,如果其中一个操作数是float ...

  7. Windows10操作技巧系列——删除最常用,最常访问,快速访问记录

    Win10除了有传统意义上的,网络历史记录外,还包含了两种本地文件浏览记录,分别是资源管理器中的“快速访问”记录,和开始菜单以及任务栏中的“最常用”“最近”“最常访问”等“最记录”. 资源管理器中的“ ...

  8. Tcl编程第四天,流程控制语句

    1. if {} { } elseif {} { } else { } 注意: 1.关键字 if elseif else 和大括号之间应该留有间距的.如果紧紧挨着会报错. 2.表条件的判断括号为大括号 ...

  9. 2015蓝桥杯分机号(C++C组)

    标题:分机号X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位.比如:751,520,321 都满足要求,而,766,918,201 就不符合要求.现 ...

  10. Array(数组)对象-->数组值的修改

    1.修改数组值: 数组对象名[下标] = 新值: 举例:原数组如下: var arr = [1,2,3,4,5] 需求:将arr数组第二个元素的值改为10,代码如下: arr[1] = 10; con ...