首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么从Executors实用程序类返回的ExecutorService的execute()方法不能自然终止

为什么从Executors实用程序类返回的ExecutorService的execute()方法不能自然终止
EN

Stack Overflow用户
提问于 2018-06-08 14:38:15
回答 2查看 276关注 0票数 1

正如我们所知,java.util.concurrent.Executors包含许多方法,例如

  • newCachedThreadPool

  • newFixedThreadPool

  • newScheduledThreadPool

  • newSingleThreadExecutor

  • newSingleThreadScheduledExecutor

它们返回包含execute(Runnable task)方法的ExecutorService。但是,当调用从上述工厂方法返回的ExecutorServiceexecute(Runnable task)时,它只能通过调用shutdown()shutdownNow()来终止

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

代码语言:javascript
复制
ExecutorService e = Executors.newSingleThreadExecutor();
e.execute(() -> system.out.println("test")); 

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

代码语言:javascript
复制
ExecutorService e = Executors.newSingleThreadExecutor();
e.execute(() -> system.out.println("test"));
e.shutdown();

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

所以我的问题是:从设计的角度来看,为什么从前述ExecutorService shutdown()工厂方法<>e257><>e158返回的的没有在没有调用或或的情况下终止?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-10 01:47:51

关于java线程:有两种类型的线程-守护进程和非守护进程。当所有非守护进程线程都完成执行时,程序终止。守护程序线程只能在程序运行时运行,并且不会阻止终止,例如garbage collector。当java程序启动时,除主线程外的所有线程都是守护进程。

newSingleThreadExecutor()和它的defaultThreadFactory()创建非守护进程线程。这在某种程度上是有道理的--你正在创建一个等待工作的线程池,它应该是你明确的关闭它的意图。

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

票数 0
EN

Stack Overflow用户

发布于 2018-06-10 00:27:51

Rui,你的例子为什么挂起的答案很简单。缺省情况下,ExecutorService中的线程是非守护进程线程,只要有非守护进程线程在运行,Java程序就不会退出。如果您不想要此行为,则只需定义一个创建守护进程线程的ThreadFactory,如下所示:

代码语言:javascript
复制
public class Test {
    static ThreadFactory mThreadFactory = new ThreadFactory() {
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    };

    public static void main(String[] args) {
        ExecutorService e = Executors.newSingleThreadExecutor(mThreadFactory);
        e.execute(new Runnable() { public void run() { System.out.println("test"); } });
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50754759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档