取消与关闭

这一章超难,暂时读不懂。

要使线程安全、快速、可靠地停止下来,并不是一件容易的事,Java没有提供任何机制来安全地终止线程。但Java提供了中断(Interruption),这是一种协作机制,能够使一个线程终止另一个线程的当前工作。

一个行为良好的软件,与勉强运行的软件之间的最主要区别就是,行为良好的软件能很完善地处理失败、关闭和取消等过程。

任务取消

取消的原因:

  • 用户请求取消
  • 有时间限制的操作
  • 应用程序事件
  • 错误
  • 关闭

其中一种协作机制是设置某个“已请求取消(Cancellation Requested)”标识,而任务定期查看该标识。

1
2
3
4
5
6
7
private volatile boolean cancelled;

public void run() {
while(!cancelled) {
doTask();
}
}

中断

上述的取消机制下,如果任务调用了一个阻塞方法,例如BlockingQueue.put,那么可能产生一个严重的问题————任务永远不会检查取消标志,因此永远不会结束。

一些阻塞库的方法支持中断,线程中断是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的或者可能的情况下停止当前工作,并转而执行其他工作。

每个线程都有一个boolean类型的中断状态,中断线程时被设置为true。

1
2
3
4
5
public class Thread {
public void interrupt(){}
public boolean isInterrupted(){}
public static boolean interrupted() {}
}

调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。

通常,中断是实现取消最合理的方式。

中断策略

由于每个线程拥有各自的中断策略,因此除非你知道中断对该线程的含义,否则就不应该中断这个线程。

响应中断

通过Future来实现取消

处理不可中断的阻塞

采用newTaskFor来封装非标准的取消

停止基于线程的服务