java - 为什么从Executors实用程序类返回的ExecutorService的execute()方法无法自然终止

标签 java currency threadpoolexecutor java-threads

众所周知,java.util.concurrent.Executors包含许多方法,例如

  • newCachedThreadPool

  • newFixedThreadPool

  • newScheduledThreadPool

  • newSingleThreadExecutor

  • newSingleThreadScheduledExecutor

    它们返回ExecutorService,其中包含execute(Runnable task)方法。然而,当调用上述工厂方法返回的ExecutorServiceexecute(Runnable task)时,只能通过调用shutdown()shutdownNow()

    来终止。

例如,如果我们将以下代码添加到 main 方法中,

ExecutorService e = Executors.newSingleThreadExecutor();
e.execute(() -> system.out.println("test")); 

调用主程序永远不会终止,因为 shutdown()shutdownNow() 未被调用。因此,在 main 中包含以下代码片段的程序将终止

ExecutorService e = Executors.newSingleThreadExecutor();
e.execute(() -> system.out.println("test"));
e.shutdown();

但是,ExecutorService 的某些子类(例如通过调用 Executors.newWorkStealingPoolForkJoinPool 返回的子类)可以在不调用 shutdown()shutdownNow() 的情况下终止

所以我的问题是:为什么从设计的角度来看,从上述以“new”开头的工厂方法返回的ExecutorServiceexecute()在不调用shutdown()shutdownNow()的情况下不会终止?

最佳答案

简单介绍一下java线程:线程有两种类型——守护线程和非守护线程。当程序的所有非守护线程都完成执行时,程序将终止。守护线程只能在程序运行时运行,并且不会阻止终止,例如garbage collector 。当java程序启动时,除了主线程之外的所有线程都是守护进程。

newSingleThreadExecutor() 及其 defaultThreadFactory()创建非守护线程。这是有道理的 - 您正在创建一个等待工作的线程池,您应该明确打算关闭它。

ForkJoinPool 另一方面,将您从底层线程池中抽象出来。因此它可以使用守护线程,因为通常您的意图是等待任务执行。

关于java - 为什么从Executors实用程序类返回的ExecutorService的execute()方法无法自然终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50754759/

相关文章:

java - Struts 2 JSON插件和通配符问题

java - ThreadPoolExecutor 没有预定义的饱和策略吗?

python - 四舍五入在 python 中向上 float $.01

string - 如何将变量格式化为字符串内的货币

executorservice - 一段时间后调用 ExecutorService

java - 如何为 @Async 方法使用自定义执行器?

java - Eclipse Luna 中的 tomcat 8 启动失败 : Error with directory [C:\Program Files\Eclipse\eclipse\lib]

java - 在构造函数中使用模拟

java - 使用 Spring MVC 的 JAXB 注释

c# - 有什么方法可以获取货币名称列表并将它们映射到货币符号?