1.线程关闭方法之一:中断
Thread的中断相关方法:
interrupt中断目标线程,设置中断状态
isInterrupted 返回目标线程的中断状态
interrupted 方法清除当前线程的中断状态,并返回之前的值。
在使用interrupted 时要注意,因为它能清除中断标志,如果返回为true,需要用这两种方法处理:
抛出InterruptedException 或者 再次调用interrupt恢复异常
2.对中断操作的正确理解: 它不会真正的中断一个正在运行的线程,而是发出中断请求,而是由线程自己在一个合适点来中断自己;在接收到InterruptedException,我们不应该屏蔽任何中断,不做任何处理
3.中断策略:
一.对于可中断的阻塞函数(Thread.sleep,join,BlockingQueue.put):a.抛出异常InterruptedException ,传递给上层调用者 b.再次调用interrupt恢复中断标志
二.不想或者无法传递InterruptedException(例如通过Runnable来定义任务) :通过interrupt来清除中断标志
线程关闭方法二:ExecutorService.submit将返回一个Future来描述任务;Future拥有一个cancel方法,该方法带有一个boolean类型的参数mayInterruptIfRunning,表示取消操作是否成功(这只是表示任务是否能够接受中断,并不是表示任务是否检测并处理中断)。如果mayInterruptIfRunning为true并且任务当前正在某个线程中运行,那么这个线程能被中断。
如果这个参数为false,那么意味着”若任务还没有启动,就不要运行它”,这种方式应该用于那些不处理中断的任务中;
除非你清楚线程的中断策略,否则不要中断线程,那么在什么情况下调用cancel可以将参数指定为true?执行任务的线程是由标准的Executor创建的,它实现了一种中断策略使得任务可以通过中断被取消,所以如果任务在标准的Executor中运行,并通过它们的Future来取消任务,那么可以设置myInterruptIfRunning。当尝试取消某个任务时,不宜直接中断线程池,因为你并不知道当中断请求到达时正在运行什么任务——只能通过任务的Future来实现取消。