0%

Java线程的几种中断

1. InterruptedException

当阻塞方法收到中断请求的时候就会抛出InterruptedException异常。
通过调用一个线程的 interrupt() 来中断该线程,如果该线程处于阻塞、限期等待或者无限期等待状态,那么就会抛出 InterruptedException,从而提前结束该线程。

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class InterruptExample{
private static class MyThread extends Thread{
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("Thread run");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread=new Thread(new MyThread());
thread.start();
thread.interrupt();
System.out.println("Main run");
}
}
输出结果
1
2
3
4
5
Main run
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at InterruptExample$MyThread.run(InterruptExample.java:6)
at java.lang.Thread.run(Unknown Source)

线程在调用interrupt()时,thread还在sleep中,所以会抛出InterruptedException,同时结束线程,这也线程就不会执行剩下的Thread run命令

2. interrupted()

interrupt() 并不能真正的中断线程,需要被调用的线程自己进行配合才行,如果一个线程有中断需求,就经常检查自己的中断标志位,如果被设置了中断标志就中止线程。线程使用interrupted()检查是否线程处于中断状态。

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class InterruptExample{
private static class MyThread extends Thread{
@Override
public void run() {
while(!interrupted()){

}
System.out.println("Thread end");
}
}
public static void main(String[] args) {
Thread thread=new Thread(new MyThread());
thread.start();
thread.interrupt();
System.out.println("Main run");
}
}
输出结果
1
2
Main run
Thread end

3. Executor 的中断操作

调用 Executor 的 shutdown() 方法会等待线程都执行完毕之后再关闭,但是如果调用的是 shutdownNow() 方法,则相当于调用每个线程的 interrupt() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyThread implements Runnable{
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("Thread running");
} catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService executorService=Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
executorService.execute(new MyThread());
}
executorService.shutdown();
System.out.println("Main end");

}
}
输出
1
2
3
4
5
6
Main end
Thread running
Thread running
Thread running
Thread running
Thread running

如果把executorService.shutdown();
换成executorService.shutdownNow();

输出
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
Main end
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at MyThread.run(MyThread.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at MyThread.run(MyThread.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at MyThread.run(MyThread.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at MyThread.run(MyThread.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at MyThread.run(MyThread.java:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Executor中断一个线程
使用submit方法它会返回一个 Future<?>对象,通过调用该对象的 cancel(true) 方法就可以中断线程。

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyThread implements Runnable{
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("Thread running");
} catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService executorService=Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyThread());
future.cancel(true);
System.out.println("Main end");

}
}
输出
1
Main end