【问题标题】:Why executor.isShutdown() returns true when there are threads still running in it's pool?为什么 executor.isShutdown() 的池中仍有线程在运行时返回 true?
【发布时间】:2019-12-12 06:37:24
【问题描述】:

shutdown() 的 Java 文档说:

关机

无效关机()

启动有序关闭,其中执行先前提交的任务,但不会接受新任务。如果已经关闭,则调用没有额外的效果。 此方法不等待先前提交的任务完成执行。使用 awaitTermination 来做到这一点。

这两个陈述不是矛盾的吗? (...之前提交的任务执行与不等待之前提交的任务完成执行)?

我用shutdown() 试用了一个示例程序。并且它会等待之前提交的任务完成,这与 shutdownNow() 不同!

为什么下面的代码在应该等待阶乘任务完成时返回I have shutdown true

public class RunnableMain {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        RunnableFactorialTask runnableFactorialTask = new RunnableFactorialTask(5);
        executor.submit(runnableFactorialTask);
        executor.shutdown();
        System.out.println(" I have shutdown.."+executor.isShutdown());
    }
}

class RunnableFactorialTask implements Runnable {

    private int num = 0;

    public RunnableFactorialTask(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        int factorial = 1;
        try {
            Thread.currentThread().sleep(6000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (int i = 2; i <= num; i++) {
            factorial *= i;
        }
        System.out.println("factorial of :" + num + " =" + factorial);
    }
}

【问题讨论】:

  • “不等待先前提交的任务完成执行”只是意味着方法调用立即返回。如果要等待,那么调用shutdown() 只会在所有任务完成后返回。 shutdown()shutdownNow() 之间的区别在于后者会尝试取消任何当前正在运行的任务,并且不会运行仍在排队的任务,而前者则什么都不做,只是让任务运行完成然后终止。跨度>
  • 你的意思是ExecutorService#shutdown()
  • @Slaw“让任务运行完成然后终止”是混乱的。(?)如果控制在调用shutdown或shutdownNow时立即返回,那么让任务运行完成的地方在哪里。这些任务似乎是独立的线程,而执行器服务本身是一个独立的线程。因此,当执行器服务立即关闭时,它所安排的任务会自行完成吗?
  • 通常,ExecutorService 管理负责执行任务的线程池。当一个任务被提交时,它被放置在一个队列中,直到其中一个池线程可以接受该任务并执行它。当您关闭 ExecutorService 时,它会停止接受 new 任务,但仍会处理已提交的任务。关闭后,一旦池线程完成其任务并且队列中没有更多剩余线程,则允许线程死亡。一旦所有池线程都死了,ExecutorService 就会终止。
  • @Slaw 你能帮我理解上面代码的o/p吗? isshutdown() 返回 true,即使正如您所解释的,线程池仍在等待任务完成。 (如果我理解正确的话..)

标签: java multithreading thread-safety


【解决方案1】:

shutdownNow()shutdown() 的调用不会阻塞。这就是文档中提到的内容。 因此,如果您致电shutdown()shutdownNow(),您将立即获得控制权,而不仅仅是在一切正常关闭之后。如果您想在调用shutdown[Now]() 后等待所有执行程序/线程终止,则必须调用awaitTermination(...),这将阻塞直到所有内容都被清理干净。这可能就是你想要的。也可以在这里查看类似问题的答案:Difference between shutdown and shutdownNow of Executor Service

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-11
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2022-01-10
    • 1970-01-01
    • 2017-10-10
    相关资源
    最近更新 更多