提前总结:

interrupt() 向当前调用者线程发出中断信号

isinterrupted() 查看当前中断信号是true还是false

interrupted() 是静态方法,查看当前中断信号是true还是false并且清除中断信号,顾名思义interrupted为已经处理中断信号。

注:interrupt()方法发出的中断信号只能被wait() sleep() join()这三个方法捕捉到并产生中断。(目前我所知)

今天在看到Thread类的isInterrupted方法可以获取线程的中断状态:

于是写了个例子想验证一下:

[java]  view plain copy
  1. public class Interrupt {
  2. public static void main(String[] args) throws Exception {
  3. Thread t = new Thread(new Worker());
  4. t.start();
  5. Thread.sleep(200);
  6. t.interrupt();
  7. System.out.println("Main thread stopped.");
  8. }
  9. public static class Worker implements Runnable {
  10. public void run() {
  11. System.out.println("Worker started.");
  12. try {
  13. Thread.sleep(500);
  14. } catch (InterruptedException e) {
  15. System.out.println("Worker IsInterrupted: " +
  16. Thread.currentThread().isInterrupted());
  17. }
  18. System.out.println("Worker stopped.");
  19. }
  20. }
  21. }

内容很简答:主线程main启动了一个子线程Worker,然后让worker睡500ms,而main睡200ms,之后main调用worker线程的interrupt方法去中断worker,worker被中断后打印中断的状态。下面是执行结果:

[vb]  view plain copy
  1. Worker started.
  2. Main thread stopped.
  3. Worker IsInterrupted: false
  4. Worker stopped.

Worker明明已经被中断,而isInterrupted()方法竟然返回了false,为什么呢?

在stackoverflow上搜索了一圈之后,发现有网友提到:可以查看抛出InterruptedException方法的JavaDoc(或源代码),于是我查看了Thread.sleep方法的文档,doc中是这样描述这个InterruptedException异常的:

[html]  view plain copy
  1. InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
[html]  view plain copy
  1. <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">注意到后面这句“当抛出这个异常的时候,中断状态已被清除”。所以isInterrupted()方法应该返回false。可是有的时候,我们需要isInterrupted这个方法返回true,怎么办呢?这里就要先说说interrupt, interrupted和isInterrupted的区别了:</span>

interrupt方法是用于中断线程的,调用该方法的线程的状态将被置为"中断"状态。注意:线程中断仅仅是设置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出InterruptedException的方法,比如这里的sleep,以及Object.wait等方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

[html]  view plain copy
  1. interrupt() merely sets the thread's interruption status. Code running in the interrupted thread can later poll the interrupted status to see if it has been requested to stop what it is doing

再来看看interrupted方法的实现:

[java]  view plain copy
  1. public static boolean interrupted() {
  2. return currentThread().isInterrupted(true);
  3. }

和isInterrupted的实现:

[java]  view plain copy
  1. public boolean isInterrupted() {
  2. return isInterrupted(false);
  3. }

这两个方法一个是static的,一个不是,但实际上都是在调用同一个方法,只是interrupted方法传入的参数为true,而inInterrupted传入的参数为false。那么这个参数到底是什么意思呢?来看下这个isInterrupted(boolean)方法的实现:

[java]  view plain copy
  1. /**
  2. * Tests if some Thread has been interrupted.  The interrupted state
  3. * is reset or not based on the value of ClearInterrupted that is
  4. * passed.
  5. */
  6. private native boolean isInterrupted(boolean ClearInterrupted);

这是一个native方法,看不到源码没有关系,参数名字ClearInterrupted已经清楚的表达了该参数的作用----是否清除中断状态。方法的注释也清晰的表达了“中断状态将会根据传入的ClearInterrupted参数值确定是否重置”。所以,静态方法interrupted将会清除中断状态(传入的参数ClearInterrupted为true),而实例方法isInterrupted则不会(传入的参数ClearInterrupted为false)。

回到刚刚的问题:很明显,如果要isInterrupted这个方法返回true,通过在调用isInterrupted方法之前再次调用interrupt()方法来恢复这个中断的状态即可:

[java]  view plain copy
  1. public class Interrupt  {
  2. public static void main(String[] args) throws Exception {
  3. Thread t = new Thread(new Worker());
  4. t.start();
  5. Thread.sleep(200);
  6. t.interrupt();
  7. System.out.println("Main thread stopped.");
  8. }
  9. public static class Worker implements Runnable {
  10. public void run() {
  11. System.out.println("Worker started.");
  12. try {
  13. Thread.sleep(500);
  14. } catch (InterruptedException e) {
  15. Thread curr = Thread.currentThread();
  16. //再次调用interrupt方法中断自己,将中断状态设置为“中断”
  17. curr.interrupt();
  18. System.out.println("Worker IsInterrupted: " + curr.isInterrupted());
  19. System.out.println("Worker IsInterrupted: " + curr.isInterrupted());
  20. System.out.println("Static Call: " + Thread.interrupted());//clear status
  21. System.out.println("---------After Interrupt Status Cleared----------");
  22. System.out.println("Static Call: " + Thread.interrupted());
  23. System.out.println("Worker IsInterrupted: " + curr.isInterrupted());
  24. System.out.println("Worker IsInterrupted: " + curr.isInterrupted());
  25. }
  26. System.out.println("Worker stopped.");
  27. }
  28. }
  29. }

执行结果:

[html]  view plain copy
  1. Worker started.
  2. Main thread stopped.
  3. Worker IsInterrupted: true
  4. Worker IsInterrupted: true
  5. Static Call: true
  6. ---------After Interrupt Status Cleared----------
  7. Static Call: false
  8. Worker IsInterrupted: false
  9. Worker IsInterrupted: false
  10. Worker stopped.

从执行结果也可以看到,前两次调用isInterrupted方法都返回true,说明isInterrupted方法不会改变线程的中断状态,而接下来调用静态的interrupted()方法,第一次返回了true,表示线程被中断,第二次则返回了false,因为第一次调用的时候已经清除了中断状态。最后两次调用isInterrupted()方法就肯定返回false了。

那么,在什么场景下,我们需要在catch块里面中断线程(重置中断状态)呢?
答案是:如果不能抛出InterruptedException(就像这里的Thread.sleep语句放在了Runnable的run方法中,这个方法不允许抛出任何受检查的异常),但又想告诉上层调用者这里发生了中断的时候,就只能在catch里面重置中断状态了。
以下内容来自:Dealing with InterruptedException

[html]  view plain copy
  1. If you catch InterruptedException but cannot rethrow it, you should preserve evidence that the interruption occurred so that code higher up on the call stack can learn of the interruption and respond to it if it wants to. This task is accomplished by calling interrupt() to "reinterrupt" the current thread, as shown in Listing 3.

Listing 3: Restoring the interrupted status after catching InterruptedException

[java]  view plain copy
  1. public class TaskRunner implements Runnable {
  2. private BlockingQueue<Task> queue;
  3. public TaskRunner(BlockingQueue<Task> queue) {
  4. this.queue = queue;
  5. }
  6. public void run() {
  7. try {
  8. while (true) {
  9. Task task = queue.take(10, TimeUnit.SECONDS);
  10. task.execute();
  11. }
  12. } catch (InterruptedException e) {
  13. // Restore the interrupted status
  14. Thread.currentThread().interrupt();
  15. }
  16. }
  17. }

那么问题来了: 为什么要在抛出InterruptedException的时候清除掉中断状态呢?
这个问题没有找到官方的解释,估计只有Java设计者们才能回答了。但这里的解释似乎比较合理:一个中断应该只被处理一次(你catch了这个InterruptedException,说明你能处理这个异常,你不希望上层调用者看到这个中断)。

JAVA interrupt、interrupted和isInterrupted的区别相关推荐

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

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

  2. Thread中interrupt()interrupted()和isInterrupted()的区别

    2019独角兽企业重金招聘Python工程师标准>>> 在java线程中,线程的状态分为6种.官方文档的解释是: /*** Thread state for a thread whi ...

  3. 【Java】interrupt、interrupted和isInterrupted的区别

    今天在看到Thread类的isInterrupted方法可以获取线程的中断状态: 于是写了个例子想验证一下: public class Interrupt {public static void ma ...

  4. 简述Thread的interrupt()、interrupted()及isInterrupted()的区别

    前言 在java Thread类中,我们会看到interrupt().interrupted()及isInterrupted(),在大多数情况下,我们都不会使用到它们,但是有一个Interrupted ...

  5. 多线程之 interrupt,interrupted,isInterrupted 方法区别

    首先看测试代码 /** * Created by Jarvis.y on 2020/11/5 * <p> * interrupt , interrupted , isInterrupted ...

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

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

  7. java---interrupt、interrupted和isInterrupted的区别

    https://www.cnblogs.com/w-wfy/p/6414801.html

  8. 对Java中interrupt、interrupted和isInterrupted的理解

    为什么80%的码农都做不了架构师?>>>    今天在看到Thread类的isInterrupted方法可以获取线程的中断状态: 于是写了个例子想验证一下: public class ...

  9. 怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?

    怎么查看线程状态 jps指令查看我当前的进程ID jstack 线程ID 示例: public class StatusDemo {public static void main(String[] a ...

最新文章

  1. 使用VM虚拟机的一点小技巧
  2. C语言竟成TIOBE年度编程语言候选!苹果iPhone 7卖得最好!
  3. MySQL集群系列2:通过keepalived实现双主集群读写分离
  4. 环境变量方式使用 Secret - 每天5分钟玩转 Docker 容器技术(158)
  5. 腾讯微博Android客户端开发——OAuth认证介绍
  6. 网络启动安装linux客户机nfs设置,NFS服务端和客户端安装配置
  7. 多种方式创建 Entity Framework Core 上下文
  8. 【16年浙江省赛H ZOJ 3965】Binary Tree Restoring 【两个dfs序还原】
  9. Tableau过期处理方法
  10. QT -- UdpSocket通信实例,使用Qt的UDP通信协议,实现局域网组播通信软件功能
  11. Python实现Excel随机抽取数
  12. filter函数 与filtfilt函数的效果区别
  13. java多线程对Runnable和Thread的理解及简述,内附实例。
  14. 防火墙的一些主流技术
  15. java.lang.UnsatisfiedLinkError: dlopen failed: file offset for the library /data/app/com.beiya.litt
  16. nvm+nodejs安装以及国内源设置
  17. Echarts世界地图以中国为中心
  18. 超声波风速风向仪介绍
  19. centos6泰拉瑞亚建立TShock服务器
  20. 世界上最大的计算机硬盘,全球第一款10TB机械硬盘现身!技术揭秘

热门文章

  1. Druid连接池开启数据库监控功能
  2. 51单片机外部中断的使用以及优先级设置
  3. 联想Y450 MAC系统SD读卡器驱动
  4. 玫瑰花瓣 c4d_在玫瑰周围打花瓣
  5. 100个优秀jQuery插件精选
  6. SPEA 功率半导体测试仪- DOT800T简介
  7. 获取当前时间一年后的日期
  8. vue通过URL传递参数
  9. 地铁听书系列之“看破不说破,81个为人处事潜规则”8月圆满收尾20220831
  10. 赛灵思 Xilinx UG1387 - Versal ACAP 硬件、IP 和平台开发方法指南(中文版) (v2020.2)