java并发编程实战-取消与关闭1

来源:互联网 发布:nat 穿透 java 编辑:程序博客网 时间:2024/05/22 11:38

1,任务取消

  1.1,Java没有提供任何机制来安全的终止线程,但它提供了中断(Interruption),这是一种协作机制,能够使一个线程终止另一个线程的当前工作

  1.2,如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的(Cancellable)
  1.3,“已请求取消”(Cancellation Requested)标志,任务会定期查看该标志,如果设置了这个标志,则任务提前结束,该标志必须为volatile类型的
2,中断
  2.1,线程中断是一种协作机制,线程可以通过这种机制来通知另外一个线程,告诉它在合适的或者可能的情况下停止当前工作,并转而执行其他的工作
  2.2,在Java的API或者语言规范中,并没有将中断与任何取消语义关联起来,但实际上,如果在取消之外的其他操作中使用中断,那么都是不合适的,并且很难支撑起更大的应用。
  2.3,每个线程都有一个boolean类型的中断状态,interrupt方法能中断目标线程,isInterrupt方法能够返回目标线程的中断状态,静态的interrupted方法将清除当前线程的中断状态并返回它之前的值。
  2.4,阻塞库方法,例如Thread.sleep和Object.wait等都会检查线程何时中断,并且发现中断时提前返回。
  2.5,阻塞方法响应中断时执行的操作包括:清除中断状态,抛出InterruptedException。
  2.6,调用Interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息,然后由线程再下一个合适的时刻中断自己。并且如果不触发InterruptException,那么中断状态将一直保持,直到有明确地清除中断状态,
  2.7,wait,sleep和join等方法,将严格地处理中断请求,当它们收到中断请求或者在开始执行时发现某个已被设置好的中断状态是,将抛出异常。
  2.8,良好的设计可以忽略中断请求,但要能使调用代码对中断请求进行某种处理。糟糕的设计可能会屏蔽中断请求,从而导致调用栈中其他代码无法对中断请求做出响应。
  2.9,使用静态的interrupted方法时应该小心,因为它会清除当前线程的中断状态,如果调用返回true,那么除非你想屏蔽这个中断,否则必须对他进行处理(可以抛出InterruptedException),或者再次调用interrupt恢复中断状态。
3,通常情况下,中断是实现取消(结束线程)的最合理的方式。
4,中断策略

  4.1,中断策略规定了线程如何解释某个中断请求,即当发生中断请求是,应该做哪些工作,哪些工作单元对于中断来说是原子操作,以及以多块的速度来响应中断。
  4.2,最合理的中断策略是:尽快退出,在必要时进行清理,通知某个所有者该线程已经退出。
  4.3,当检测到中断请求时,任务不需要放弃所有的操作,只需要记住该中断,并且一个合适的点(比如完成了数据的备份)之后抛出InterruptedException或者表示已收到中断请求。
  4.4,如果在除了将InterruptedException传递给调用者外还需要执行其他操作,那么应该在捕获InterruptedException之后恢复中断状态:Thread.currentThread().interrupt();
  4.5,由于每个线程拥有各自的中断策略,因此除非你知道中断对该线程的含义,否则就不应该中断这个线程。
5,响应中断
  5.1,当调用可中断的阻塞函数时,例如Thread.sleep或者BlockingQueue.put等,有两种策略可以处理:传递异常,恢复中断状态。

  5.2,恢复中断应该首先在本地保存中断状态,并在返回前恢复状态,而不是在捕获后立即恢复,例如:

public Task getNextTask(BlockingQueue<Task> queue) {boolean interrupted = false;try {while (true) {try {return queue.take();} catch (InterruptedException e) {interrupted = true;// 重新尝试}}} finally {if (interrupted) {Thread.currentThread().interrupt();}}}





原创粉丝点击