多线程-interrupt
中断一个线程非常简单,只需要在其他线程中对目标线程调用interrupt()
方法,目标线程需要反复检测自身状
态是否是interrupted状态,如果是,就立刻结束运行。
1、案例一
package com.example.one;
/**
* @author tom
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new MyThread();
t.start();
// 暂停1毫秒
Thread.sleep(1);
// 中断t线程
t.interrupt();
// 等待t线程结束
t.join();
System.out.println("end");
}
}
class MyThread extends Thread {
@Override
public void run() {
int n = 0;
while (!isInterrupted()) {
n++;
System.out.println(n + " hello!");
}
}
}
# 输出
......
81 hello!
82 hello!
83 hello!
end
上述案例很简单,就是调用mythread的interrupt()方法,MyThread内部run中对线程中的中断状态进行判断,并
没有真正意义上中断线程。
2、案例二
package com.example.two;
/**
* @author tom
*/
public class ThreadInterruptTest {
public static void main(String[] args) {
try {
Thread t = new MyThread();
t.start();
// 暂停1毫秒
Thread.sleep(1);
System.out.println("before invoke interrupted");
// 中断t线程
t.interrupt();
System.out.println("before main join");
// 等待t线程结束
t.join();
System.out.println("end");
} catch (InterruptedException e) {
System.out.println("main interrupted!");
}
}
}
class MyThread extends Thread {
@Override
public void run() {
int n = 0;
try {
while (!isInterrupted()) {
n++;
System.out.println(n + " hello!");
}
// mythread如果被调用了interrupt方法,并且mythread线程run方法中有抛出InterrutpedException的方法,就会抛出,没有就不会抛出
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("mythread interrupted");
}
}
}
# 输出
......
92 hello!
93 hello!
before invoke interrupted
94 hello!
before main join
mythread interrupted
end
该案例就是案例一中,对MyThread中run方法新增了Thread.sleep方法调用,并catch了InterruptedException
此时发现MyThread中抛出了InterruptedException,但是案例一中并没有抛出。
所以对于处在sleep()方法阻塞下的线程,interrupt()方法会使线程抛出一个异常。
3、案例三
package com.example.three;
/**
* @author tom
*/
public class ThreadInterruptTest2 {
public static void main(String[] args) {
try {
Thread t = new MyThread2();
t.start();
Thread.sleep(1000);
// 中断t线程
t.interrupt();
System.out.println("before main join");
// 等待t线程结束
t.join();
System.out.println("end");
} catch (InterruptedException e) {
System.out.println("main interrupted!");
}
}
}
class MyThread2 extends Thread {
@Override
public void run() {
Thread hello = new HelloThread();
// 启动hello线程
hello.start();
try {
// 等待hello线程结束
hello.join();
} catch (InterruptedException e) {
System.out.println("mythread interrupted!");
}
hello.interrupt();
}
}
class HelloThread extends Thread {
@Override
public void run() {
int n = 0;
while (!isInterrupted()) {
n++;
System.out.println(n + " hello!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("hello interrupted");
break;
}
}
}
}
# 输出
1 hello!
2 hello!
3 hello!
4 hello!
5 hello!
6 hello!
7 hello!
8 hello!
9 hello!
10 hello!
before main join
mythread interrupted!
end
hello interrupted
比案例二中更复杂了,嵌套线程调用。但是基本逻辑一样,就是在调用线程中断方法,线程的具体实现run中具有
join调用,会抛出InterruptedException。
所以对于处在sleep()、wait()和join()方法阻塞下的线程,interrupted方法会使线程抛出一个异常。
4、总结
**interrupt()不会去真正意义上的打断一个正在运行的线程,而是修改这个线程的中断状态码(interrupt **
status)。同时,对于处在sleep()、wait()和join()方法阻塞下的线程,该方法会使线程抛出一个异常。
与interrupt类似的方法:
java.lang.Thread#isInterrupted()
判断目标线程是否被中断,不会清除中断标记。
java.lang.Thread#interrupted
判断目标线程是否被中断,会清除中断标记。