使用ExecutorService
返回的Executors.newSingleThreadExecutor()
时,如何中断它?
答案 0 :(得分:36)
要执行此操作,您需要将submit()
任务ExecutorService
转移到execute()
,而不是调用Future
。执行此操作时,将返回Future
,可用于操作计划任务。特别是,您可以在关联的ExecutorService
上调用cancel(true)
来中断当前正在执行的任务(如果任务尚未开始运行,则完全跳过执行)。
顺便说一下,Executors.newSingleThreadExecutor()
返回的对象实际上是{{1}}。
答案 1 :(得分:5)
中断执行程序内部管理线程的另一种方法是调用shutdownNow(..)
上的ExecutorService
方法。但请注意,与@ erickson的解决方案相反,这将导致整个ThreadPoolExecutor
变得不适合进一步使用。
我发现这种方法在不再需要ExecutorService
的情况下特别有用,并且在Future
实例上保持标签是不必要的(这是exit(..)
方法的一个主要示例你的申请)。
来自ExecutorService#shutdownNow(..)
javadocs的相关信息:
尝试停止所有正在执行的任务,停止处理 等待任务,并返回正在等待的任务列表 执行。
除了努力尝试停止处理之外,没有任何保证 积极执行任务。例如,典型的实现方式 通过Thread.interrupt取消,因此任何无法响应的任务 中断可能永远不会终止。
答案 2 :(得分:0)
一种正确的方法是为执行器服务定制/注入ThreadFactory,并从线程工厂中获得创建的线程的句柄,然后您可以安排一些任务来中断感兴趣的线程。
用于覆盖方法的演示代码部分" newThread"在ThreadFactory中:
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中的线程。