Loading

Java并发学习之中断策略

一. 中断策略学习

我们前面学习了任务包含取消策略,同样的,线程应该包含中断策略。

1.中断策略规定线程如何解释某个中断请求:当发现中断请求时,线程应该做哪些工作(如果需要的话),哪些工作单元对于中断来说是原子操作,以及以多快的速度来响应中断。

2.最合理的中断策略是某种形式的线程级取消操作或者服务级取消操作:尽快退出,在必要时清理,通知某个所有者该线程已经退出。

3.除此之外还可以建立其他的中断策略:例如暂停服务或者重新开始服务,但对于哪些包含非标准中断策略的线程或线程池,只能用于能知道这些策略的任务中。

4.区分任务和线程对中断的反应是很重要的。一个中断请求可以有一个或多个接收者:中断线程池中的某个工作者线程,同时意味着“ 取消当前任务 ” 和 “ 关闭工作者线程 ”。

5.任务不会在其自己拥有的线程中执行,而是在某个服务(例如线程池)拥有的线程中执行。

6.对于非线程所有者的代码来说(例如,对于线程池而言,任何在线程池实现之外的代码就是非线程所有者代码)应该小心地保存中断状态,这样拥有线程的代码才能对中断做出响应(即使 非线程所有者 代码也可以对中断做出响应)。
这就是为什么大多数可阻塞的库函数都只是抛出InterruptedException 作为中断响应。它们永远都不会在某个由自己拥有的线程中运行,因此它们为任务或者库代码实现了最合理的取消策略:尽快退出执行流程,并把中断信息传递给调用者,从而使调用栈中的上层代码可以采取进一步的操作。

7.当检查到中断请求时,任务并不需要放弃所有的操作:它可以推迟处理中断请求,并直到某个更合适的时刻。因此需要记住中断请求,并在完成当前任务后抛出InterruptedException或者表示已收到中断请求。

8.任务不应该对执行该任务的线程的中断策略做出任何假设,除非该任务被专门设计为在服务中运行,并且在这些服务中包含特定的中断策略。

9.无论任务把中断视为取消,还是其他某个中断响应操作,都应该小心地保存执行线程的中断状态。
如果除了将InterruptedException传递给调用者外还需要执行其他操作,那么应该在捕获InterruptedException之后恢复中断状态:Thread.currentThread().interrupt();

10.正如任务代码不应该对其执行所在的线程的中断策略做出假设,执行取消操作的代码也不应该对线程的中断策略做出假设。

11.线程应该只能由其所有者中断,所有者可以将线程的中断策略信息封装在某个合适的取消机制中,例如shutdown方法。

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

二.响应中断

1.当调用可中断的阻塞函数时,例如:Thread.sleep 或者 BlockingQueue.put等,有两种实用策略可用于处理InterruptedException:
1)传递异常(可能在执行某个特定任务的清除操作后),从而使我们的方法也成为可中断的阻塞方法。
2)恢复中断状态,从而使调用栈中的上层代码能够对其进行处理。

传递InterruptedException就是将它抛给调用者,让调用者处理

BlockingQueue<Task> queue;
...
pubic Task getNextTask() throws InterruptedException{
   
  return queue.take();
}

如果不想或者无法传递InterruptedException,那么需要寻找另一种方式来保存中断请求:
a.一种标准的方式就是通过再次调用interrupt来恢复中断状态。
b.我们不能屏蔽InterruptedException(例如在catch块中捕获到异常却不做任何处理)除非我们的代码中实现了线程中断策略。由于大多数代码并不知道它们将在哪个线程中运行,因此应该保存中断状态。

注意:只有实现了线程中断策略的代码才可以屏蔽中断请求,在常规的任务和库代码中都不应该屏蔽中断请求。

2.对于一些不支持取消但仍可以调用可中断阻塞方法的操作,它们必须在循环中调用这些可中断阻塞方法,并在发现中断后重新尝试,在这种情况下,它们应该在本地保存中断状态,并在返回前恢复中断状态而不是在捕获InterruptedException时恢复中断状态。

如下:

public Task getNextTask(BlockingQueue<Task> queue>){
   
   boolean interrupted = false;
   try{
   
     while(true){
   
       try{
   
           r
posted @ 2020-11-22 15:37  文牧之  阅读(32)  评论(0)    收藏  举报  来源