使用 Executors.newSingleThreadExecutor()
返回的ExecutorService
时,如何中断它?
为此,您需要将任务submit()
给 ExecutorService
,而不是调用 execute()
。执行此操作时,将返回可用于操作计划任务的Future
。具体而言,您可以在关联的Future
上调用cancel(true)
以中断当前正在执行的任务(如果任务尚未开始运行,则完全跳过执行(。
顺便说一下,Executors.newSingleThreadExecutor()
返回的对象实际上是一个ExecutorService
。
中断执行程序内部管理的线程的另一种方法是在ExecutorService
上调用 shutdownNow(..)
方法。但是请注意,与@erickson的解决方案相反,这将导致整个ThreadPoolExecutor
变得不适合进一步使用。
我发现这种方法在不再需要ExecutorService
并且不需要密切关注Future
实例的情况下特别有用(一个典型的例子是应用程序exit(..)
方法(。
来自 ExecutorService#shutdownNow(..)
javadocs 的相关信息:
尝试停止所有活动正在执行的任务,停止处理 等待任务,并返回正在等待的任务的列表 执行。
除了尽最大努力尝试停止处理之外,无法保证 积极执行任务。例如,典型的实现将 通过 Thread.interrupt 取消,因此任何无法响应的任务 中断可能永远不会终止。
一种正确的方法是为ExecutorService
自定义/注入ThreadFactory
,并从线程工厂中获取创建的线程的句柄,然后您可以安排一些任务来中断感兴趣的线程。
ThreadFactory
中覆盖方法newThread
的演示代码部分:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
}, 5, TimeUnit.SECONDS);
return thread;
}
}
然后,您可以使用以下代码构造ExecutorService
实例:
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
然后在 5 秒后,中断信号将发送到 ExecutorService
中的线程。