如何中断ExecutorService的线程
使用Executors.newSingleThreadExecutor()
返回的Executors.newSingleThreadExecutor()
,如何中断它?
为此,您需要将任务submit()
给ExecutorService
,而不是调用execute()
。 执行此操作时,将返回可用于操作计划任务的Future
。 特别是,您可以在关联的Future
上调用cancel(true)
来中断当前正在执行的任务(如果任务尚未开始运行,则完全跳过执行)。
顺便说一句, Executors.newSingleThreadExecutor()
返回的对象实际上是一个ExecutorService
。
中断执行程序内部管理线程的另一种方法是在ExecutorService
上调用shutdownNow(..)
方法。 但请注意,与@ erickson的解决方案相反,这将导致整个ThreadPoolExecutor
变得不适合进一步使用。
我发现这种方法在不再需要ExecutorService
情况下特别有用,并且在Future
实例上保留标签是不必要的(这是你应用程序的exit(..)
方法的一个主要例子)。
来自ExecutorService#shutdownNow(..)
javadocs的相关信息:
尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。
除了尽力尝试停止处理主动执行任务之外,没有任何保证。 例如,典型的实现将通过Thread.interrupt取消,因此任何未能响应中断的任务都可能永远不会终止。
一种正确的方法是为执行器服务定制/注入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() { 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秒后,中断信号将被发送到执行器服务中的线程。