07_02_线程中断

线程中断

中断线程,指的是向线程发起一个中断信号。

其目的是为了中断线程,对象是线程,而不是线程内运行的任务。

一、中断策略

任务有取消策略,线程也有对应的中断策略。

  • 中断策略:规定了线程如何解释某个中断请求
  • 中断策略,不是指如何中断线程,而是指线程在收到中断后,如何处理这个中断请求

具体来说,就是在线程发现中断时:

  • 该做什么工作(需要的话)
  • 哪些工作单元对于中断来说是原子操作
  • 以多快的速度响应中断

每个线程都有各自的中断策略,可以有不同的处理。

二、屏蔽中断策略

最简单的中断策略,就是屏蔽忽略线程的中断。

1
2
3
4
5
6
7
8
9
10
11
12
13
class IgnoreThread extends Thread {
public void run() {
Runnable task;
for(;;) {
try {
task = tasks.take();
task.run();
} catch (InterruptedException e) {
// 屏蔽忽略所有的中断
}
}
}
}

这种完全屏蔽中断的行为,不是一种很合理的方式,过于粗暴。

三、结束线程策略

最合理的中断策略,就是线程级取消操作或服务级取消操作:

  • 线程发现中断后,尽快退出结束,在必要时进行清理,通知某个所有者该线程已经退出

比如说,线程可以运行多个任务,如果中断了线程,那还得等任务都执行完之后才能退出。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ExitThread extends Thread {
public void run() {
try {
Runnable task;
for(;;) {
// 检查是否发生了中断
if (Thread.currentThread().isInterrupted()) {
break;
}
task = tasks.take();
task.run();
}
} catch (InterruptedException e) {
// 中断线程
} finally {
// 清理
cleanup();
// 通知结束
notifyExit();
}
}
}

收到中断后结束线程,算是一种比较合理的中断策略了。

四、重启线程策略

还有其他的中断策略,比如暂停服务或重启服务:

  • 线程收到中断后,它先是销毁当前线程,然后再重新创建一个新的线程来替代

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class RebuildThread extends Thread {
public void run() {
try {
Runnable task;
for(;;) {
// 检查是否发生了中断
if (Thread.currentThread().isInterrupted()) {
break;
}
task = tasks.take();
task.run();
}
} catch (InterruptedException e) {
// 中断线程
} finally {
// 重启新线程
createWorker(tasks);
}
}
}

这种重启线程策略,实际在线程池中可能会用到。

因为如果一个线程异常退出后,线程池可能需要补充一个新线程来恢复之前的规模。

总结

中断线程:

  • 中断线程,指的是向线程发起一个中断信号
  • 中断线程,对象是线程,而不是线程内运行的任务

线程如何解释某个中断请求:

  • 该做什么工作(需要的话)
  • 哪些工作单元对于中断来说是原子操作
  • 以多快的速度响应中断

中断策略:

  • 屏蔽中断策略
  • 结束线程策略
  • 重启线程策略
作者

jiaduo

发布于

2022-05-15

更新于

2023-04-03

许可协议