最近在总结multithread方面的知识。这篇主要介绍线程的取消。
在任务、线程、服务以及应用程序等模块中的生命周期结束问题,可能会增加他们在设计和实现时的复杂性。Java并没有提供某种抢占式的机制来取消操作或者终结线程。相反,它提供了一种协作式的中断机制来实现实现取消操作,但这要依赖于如何构建取消操作的协议,以及能否遵循这些协议。通过使用FutureTask和Executor框架,可以帮助我们构建可取消的任务和服务。
ExecutorService.submit 将返回一个Future来描述任务,future拥有一个cancel方法,该方法带有一个boolean类型的参数mayInterruptIfRunning,表示操作是否成功,(这只表示任务能否接受中断,而不是表示任务能否检测并处理中断)如果mayInterruptIfRunning为true并且任务正在某个线程中运行,那么这个线程能被中断。如果为false,那么表示 若任务还没有启动,就不要启动它, 这种方式应该用于那些不处理中断的任务中。
除非你清楚线程的中断策略,否则不要中断线程,那么什么时候可以指定cancel的参数为true?执行任务的线程是由标准的Executor创建的,它体现了一种中断策略使得任务可以通过中断被取消,所以如果任务在Executor中运行,并通过他们的Future取消任务,那么可以设置mayInterruptIfRunning。当尝试取消某个任务时,不宜直接中断线程池,因为你并不知道当中断请求到达时正在运行什么任务--只能通过任务的future来实现取消。
1.通过Future实现取消
Future<?> task = executor.submit(r);
try{
task.get(timeout,timeunit);
}catch(TimeoutException to){
//接下来任务将被取消
}catch(ExecutionException eo){
//如果任务中抛出了异常,那么重新抛出异常
throw launderThrowable(eo.getCause());
}finally{
task.cancel(true);//如果任务已经结束,那么取消操作也不会带来任何影响;如果任务正在运行,那么将被中断
}