Java并发编程实战笔记5:取消与关闭

任务取消

若是外部代码能在某个操做正常完成以前将其置入“完成”状态,那么这么操做就能够称为可取消的。Java中有一些协做式的机制,使得请求取消的任务和代码都遵循一种协商好的协议。编程

线程中断是一种用于中止线程的协做机制,线程能够经过这种机制来通知另外一个线程,告诉它在合适的或者可能的状况下中止当前工做。并发

每一个线程都有一个布尔变量表示其中断状态。使用interrupt()方法将中断状态设置为ture;使用isInterrupted()判断线程的中断状态;使用Thread.interrupted()判断当前线程的中断状态,并将当前线程的中断状态设置为false。函数

调用interrupt()方法并不意味着当即中止目标线程正在进行的工做,而只是传递了请求中断的消息,而后由线程在合适的时刻中断本身。一般,中断是实现取消的最合理的方式。.net

当检查到中断请求后,任务并不须要放弃全部的操做,它能够推迟处理中断请求,并直到某个更合适的时候。所以须要记住中断请求,并在完成当前任务后抛出InterruptedException或者表示已经收到中断请求。线程

响应中断

当调用可中断的阻塞函数时,如Thread.sleep()或者BlokcingQueue.put(),Object.wait()等。能够在别的线程中调用当前线程对象的interrupt方法触发这些函数抛出InterruptedException异常,有两种策略来处理:对象

  • 传递异常,从而使你的方法也成为可中断的阻塞方法
  • 恢复中断状态,从而使调用栈中的上层代码可以对其进行处理。

当你捕获到InterruptedException异常后,当前线程的中断状态已经被修改成false(表示线程未被中断);此时你若可以处理中断,则不用理会该值;但若是你继续向上抛InterruptedException异常,你须要再次调用interrupt方法,将当前线程的中断状态设为true。blog

只有实现了线程中断策略的代码才能屏蔽中断请求,不能捕获异常却不作处理。ci

使用Future实现取消

Future有一个cancel(boolean mayInterruptIfRunning) 方法:该方法是非阻塞的,该方法能够用来(尝试)终止一个任务。get

  • 若是任务运行以前调用了该方法,那么任务就不会被运行;
  • 若是任务已经完成或者已经被取消,那么该方法方法不起做用;
  • 若是任务正在运行,而且 cancel 传入参数为 true,那么便会去终止与 Future 关联的任务。

cancel(false) 与 cancel(true)的区别在于,cancel(false)只取消已经提交但尚未被运行的任务(即任务就不会被安排运行);而 cancel(true) 会取消全部已经提交的任务,包括正在等待的和正在运行的任务。it

参考资料

相关文章
相关标签/搜索