在Java中没有一种安全的抢占方法来停止线程,因此也就没有安全的抢占式方法来停止任务。只有一些协作式的机制,使请求取消的任务和代码都遵循一种协商好的协议。
调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。 它并不会真正地中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一合适的时刻中断自己。
你是中断任务还是中断线程,含义并不相同。比如在线程池里,你只是中断任务,处理完成异常,清除状态之后,只需要简单返回就行,但如果确定是要中断线程,则要进行其它考虑了。
当调用可中断的阻塞函数时,有两种实用策略可用于处理InterruptedException
传递异常(可能在执行某个特定于任务的清除操作之后),从而使得你的方法也成为可中断的阻塞方法。恢复中断状态,从而使得调用栈中的上层代码能够对其处理。 注意:只有实现了线程中断策略的代码才可以屏蔽中断请求。在常规的任务和库代码中都不应该屏蔽中断请求。如果我们需要知道这些任务,并且不想直接中断而是进行继续的后续处理,则可以使用TrackingExecutor找出哪些任务已经开始但还没有正常完成。在Executor结束后,getCancelledTasks返回被取消的任务清单。
public class TrackingExecutor extends AbstractExecutorService{ private final ExecutorService exec; private final Set<Runnable> tasksCancelledAtShutdown = Collections.synchronizedSet(new HashSet<Runnable>()); .... public List<Runnable> getCancelledTasks(){ if(!exec.isTerminated()) throw new IllegalStateException(....); return new ArrayList<Runnable>(tasksCancelledAtShutdown); } public void executor(final Runnable runnable){ //重点看这一段代码 try{ runnable.run(); }finally{ if(isShutdown() && Thread.currentThread().isInterrupted()) tasksCancelledAtShutdown.add(runnable); } } // 将ExecutorService其它方法委托给exec } //另一段使用TrackingExecutor类的代码 public synchronized void stop() throws InterruptedException{ try{ saveUncrawled(exec.shutdownNow()); if(exec.awaitTermination(TIMEOUT,UNIT)) saveUncrawled(exec.getCancelledTasks); }finally{ exec = null; } }ANSWER:不会退出,因为只要有非daemon线程未退出,JVM就不会退出。
