如何中断ExecutorService的线程

时间:2012-02-14 16:52:51

标签: java multithreading concurrency executorservice

使用ExecutorService返回的Executors.newSingleThreadExecutor()时,如何中断它?

3 个答案:

答案 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中的线程。