如何中断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秒后,中断信号将被发送到执行器服务中的线程。