【Java多线程】Thread类中interrupt()、interrupted() 和isInterrupted() 方法详解(九)

方法官方说明

interrupt()方法

  

  其作用是中断此线程(此线程不一定是当前线程,而是指调用该方法的Thread实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行。

interrupted()方法

  

  作用是测试当前线程是否被中断(检查中断标志),返回一个boolean并清除中断状态,第二次再调用时中断状态已经被清除,将返回一个false。

isInterrupted()方法

  

  作用是只测试此线程是否被中断 ,不清除中断状态。

示例说明

验证interrupt()方法

  定义一个MyThread类,继承Thread,如下:

 1 class MyThread extends Thread {
 2     @Override
 3     public  void run() {
 4         long num = 1;
 5         for (int i = 1; i < 1000000000; i++) {
 6             num = num * (num + i) % 1000000000;
 7         }
 8         System.out.println("结果是" + num);
 9         System.out.println("退出线程" + Thread.currentThread().getName());
10     }
11 }

  在main方法中测试

 1 public class TestInterrupt {
 2 
 3     public static void main(String[] args ) {
 4         MyThread thread=new MyThread();
 5         thread.start();
 6         thread.interrupt();
 7         // 测试 isInterrupted()函数
 8         System.out.println("第一次调用thread.isInterrupted():"+thread.isInterrupted());
 9         System.out.println("第二次调用thread.isInterrupted():"+thread.isInterrupted());
10         System.out.println("thread是否存活:"+thread.isAlive());
11     }
12 
13 }

  输出如下:

  

  分析:

  1. 调用interrupt()方法后,线程设置一个中断标志
  2. 结果看出调用interrupt()方法后,线程仍在继续运行,并未停止,两个isInterrupted()方法都会输出true,也说明isInterrupted()方法并不会清除中断状态。

验证interrupt()方法

  • 代码一

  下面我们把代码修改一下,多加两行调用interrupted()方法:

 1 public class TestInterrupt {
 2 
 3     public static void main(String[] args ) {
 4         MyThread thread=new MyThread();
 5         thread.start();
 6         thread.interrupt();
 7         // 测试 isInterrupted()函数
 8         System.out.println("第一次调用thread.isInterrupted():"+thread.isInterrupted());
 9         System.out.println("第二次调用thread.isInterrupted():"+thread.isInterrupted());
10         // 测试 interrupted()函数
11         System.out.println("第一次调用thread.interrupted():"+thread.interrupted());
12         System.out.println("第二次调用thread.interrupted():"+thread.interrupted());
13         System.out.println("thread是否存活:"+thread.isAlive());
14     }
15 }

  输出如下:

  

  从输出结果看,可能会有疑惑,为什么后面两个interrupted方法输出的都是false,而不是预料中的一个true一个false?注意!!!这是一个坑!!!上面说到,interrupted()方法测试的是当前线程是否被中断,当前线程!!!当前线程!!!这里当前线程是main线程,而thread.interrupt()中断的是thread线程,这里的此线程就是thread线程。所以当前线程main从未被中断过,尽管interrupted()方法是以thread.interrupted()的形式被调用,但它检测的仍然是main线程而不是检测thread线程,所以thread.interrupted()在这里相当于main.interrupted()

  查看interrupted()源码

1 public class Thread implements Runnable {
2     .....
3 
4     public static boolean interrupted() {
5         return currentThread().isInterrupted(true);
6     }
7 
8     .....
9 }  

  interrupted()是一个静态方法,调用的currentThread()方法来获取当前线程(在代码中当前线程即主线程main) 

  对于这点,下面我们再修改进行测试。

 1 public class TestInterrupt {
 2 
 3     public static void main(String[] args ) {
 4         MyThread thread=new MyThread();
 5         thread.start();
 6         thread.interrupt();
 7         // 测试 isInterrupted()函数
 8         System.out.println("第一次调用thread.isInterrupted():"+thread.isInterrupted());
 9         System.out.println("第二次调用thread.isInterrupted():"+thread.isInterrupted());
10         // 测试 interrupted()函数
11         System.out.println("第一次调用thread.interrupted():"+Thread.currentThread().interrupted());
12         System.out.println("第二次调用thread.interrupted():"+Thread.currentThread().interrupted());
13         System.out.println("thread是否存活:"+thread.isAlive());
14     }
15 }

  运行结果前面相同

  

  • 代码二
 1 public class TestInterrupt2 {
 2 
 3     public static void main(String[] args ) {
 4         Thread.currentThread().interrupt();
 5         // 测试 isInterrupted()函数
 6         System.out.println("第一次调用Thread.currentThread().isInterrupted():"+Thread.currentThread().isInterrupted());
 7         System.out.println("第二次调用Thread.currentThread()v.isInterrupted():"+Thread.currentThread().isInterrupted());
 8         // 测试 interrupted()函数
 9         System.out.println("第一次调用Thread().interrupted():"+Thread.currentThread().interrupted());
10         System.out.println("第二次调用Thread().interrupted():"+Thread.currentThread().interrupted());
11         System.out.println("Thread.currentThread()是否存活:"+Thread.currentThread().isAlive());
12     }
13 
14 }

  运行结果:

  

  这里都是针对当前线程在操作,如果interrupted()方法有检测中断并清除中断状态的作用

  • 代码三

  若果想要是实现调用interrupt()方法真正的终止线程,则可以在线程的run方法中做处理即可,比如直接跳出run()方法使线程结束,视具体情况而定,下面是一个例子。

 1 public class TestInterrupt3 {
 2 
 3     public static void main(String[] args) {
 4         MyThread3 thread=new MyThread3();
 5         thread.start();
 6         thread.interrupt();
 7         //sleep等待10秒,等myThread运行完
 8         try {
 9             Thread.currentThread().sleep(10000);
10         } catch (InterruptedException e) {
11             e.printStackTrace();
12         }
13         System.out.println("myThread线程是否存活:"+thread.isAlive());
14     }
15 
16 }
17 
18 class MyThread3 extends Thread {
19 
20     @Override
21     public void run() {
22         long num = 1;
23         for (int i = 1; i < 1000000000; i++) {
24             num = num * (num + i) % 1000000000;
25             if (this.isInterrupted()) {
26                 System.out.println("通过this.isInterrupted()检测到中断");
27                 System.out.println("第一个interrupted()" + Thread.interrupted());
28                 System.out.println("第二个interrupted()" + Thread.interrupted());
29                 System.out.println("因为检测到中断,所以跳出循环,线程到这里结束,因为后面没有内容了");
30                 return;
31             }
32         }
33         System.out.println("结果是" + num);
34         System.out.println("退出线程" + Thread.currentThread().getName());
35     }
36 }

  运行结果:

  

  • 代码四

  interrupt() 除了给线程设置中断标志,还能将处于中断状态的线程唤醒,代码如下

 1 public class TestInterrupt4 {
 2 
 3     public static void main(String[] args) {
 4         MyThread4 thread=new MyThread4();
 5         thread.start();
 6         try {
 7             Thread.sleep(1000);
 8         } catch (InterruptedException e) {
 9             e.printStackTrace();
10         }
11         //  除了给线程设置中断标志,还能将处于中断状态的线程唤醒
12         thread.interrupt();
13     }
14 
15 }
16 
17 class MyThread4 extends Thread {
18     @Override
19     public  void run() {
20         long start = System.currentTimeMillis();
21         try {
22             Thread.sleep(100000000);
23         } catch (InterruptedException e) {
24             e.printStackTrace();
25         }
26         long end = System.currentTimeMillis();
27         System.out.println("线程休眠时间为" + (end - start) + "毫秒");
28     }
29 }

  运行结果:

  

最后总结

  关于这三个方法,interrupt() 是给线程设置中断标志;interrupted() 是检测中断并清除中断状态;isInterrupted() 只检测中断。还有重要的一点就是interrupted() 作用于当前线程,是静态方法,interrupt() 和isInterrupted() 作用于此线程,即代码中调用此方法的实例所代表的线程。

原文链接:https://blog.csdn.net/qq_39682377/article/details/81449451

原文地址:https://www.cnblogs.com/h--d/p/14557647.html