MyThread.class
package cn.yilong.edcsapiservice.thread; public class MyThread extends Thread { @Override public void run() { System.out.println("开始睡觉"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束睡觉"); synchronized (MyThread.class){ for (int i=0; i<100; i++){ System.out.print(i+","); } System.out.println(); String name = Thread.currentThread().getName(); System.out.println(name + ": " + this.isInterrupted()); System.out.println("test--------------------"); System.out.println(); } } }
Run.class
package cn.yilong.edcsapiservice.thread; public class Run2 { public static void main(String[] args) { Thread ct = Thread.currentThread(); ct.setName("mainThread"); try { MyThread t = new MyThread(); t.setName("myThread"); t.start(); t.interrupt(); // 如果t线程已经结束,再调中断方法,不做任何处理 synchronized (MyThread.class) { String name = Thread.currentThread().getName(); System.out.println(name + ": " + t.interrupted()); //虽然是t线程调用,但底层真正调用不是t,而是当前main方法的线程, 执行实际操作是 Thread.currentThread().isInterrupted() 即mainThread线程 System.out.println(t.getName() + ": " + t.isInterrupted()); System.out.println("main-----------------------------"); System.out.println(); } } catch (Exception e) { System.out.println("main catch"); e.printStackTrace(); } } }
mainThread: false
myThread: true
main-----------------------------
开始睡觉
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.yilong.edcsapiservice.thread.MyThread.run(MyThread.java:8)
结束睡觉
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
myThread: false
test--------------------
interrupt() 方法
interrupt()本质是 给调用该方法的线程做一个标记, 这个标记默认初始值是: false, 调用后变成: true,
所以说, 做标记并不能停止这个线程. 而废弃的stop()方法是直接停止这个线程. 这是根本区别.
线程对象调用interrupt()方法时, 我们想中断这个线程, 需要人为写逻辑进行中断,
通常存在两种情况(实际还有其他,源码注释上有解释):
1. 线程状态:正在运行中, 此时如果t线程调用了interrupt()方法, 那么,t线程会立刻被做上标识: false变为true, (当然,如果t线程调用interrupt()前刚好正常执行结束了,
那么标记不会变更,依然时false) t线程如果还在执行中, 依然继续执行下去, 被标记不会受到任何影响(重点), 接着,我们在t线程的执行方法run()中通过调用 interrupted()或
isInterrupted()来进行手动结束run()方法的执行.
啰嗦下:
(1) t.interrupt()执行后, 打标记: false变true,
run()方法中 t.interrupted()和t.isInterrupted()会获取到这个标记,值为false或true.
(2) t.interrupted()方法注意两点:
1.指代当前调用的线程, 也就是说, 如果在mian()方法中, 执行了t.interrupted()方法, 实际执行的并不是t线程, 而是main线程(特别注意)
2.t.interrupted()方法执行后,会返回一个结果true或false, 同时它还会执行另一步操作: 将t线程标记的结果重置为默认初始值: false. 所以,不要第二次调用它.(特别注意)
(3) t.isInterrupted()方法指的就是t线程的中断标记: true,或false, 它只返回结果, 不会做其他的操作.
2. 线程状态: 阻塞中, 比如调用了sleep(), 或wait(), 或join() 阻塞方法, 此时如果t线程调用了interrupt()方法, 那么,t线程会立刻被做上标识: false变为true, 同时,
阻塞中的t线程此时监测到自己中断标识变为了true, 便抛出了InterruptedException异常, 同时, 将t线程标记的结果重置为默认初始值: false (重点).
接着,我们在t线程的执行方法run()中通过try--catch捕获该异常,然后手动处理结束run()方法.