正如我们所知,java.util.concurrent.Executors
包含许多方法,例如
newCachedThreadPool
newFixedThreadPool
newScheduledThreadPool
newSingleThreadExecutor
newSingleThreadScheduledExecutor
它们返回包含execute(Runnable task)
方法的ExecutorService
。但是,当调用从上述工厂方法返回的ExecutorService
的execute(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.newWorkStealingPool
或ForkJoinPool
返回的子类)可以在不调用shutdown()
或shutdownNow()
的情况下终止
所以我的问题是:从设计的角度来看,为什么从前述ExecutorService
shutdown()
工厂方法<>e257><>e158返回的的没有在没有调用或或的情况下终止?
发布于 2018-06-10 01:47:51
关于java线程:有两种类型的线程-守护进程和非守护进程。当所有非守护进程线程都完成执行时,程序终止。守护程序线程只能在程序运行时运行,并且不会阻止终止,例如garbage collector。当java程序启动时,除主线程外的所有线程都是守护进程。
newSingleThreadExecutor()
和它的defaultThreadFactory()
创建非守护进程线程。这在某种程度上是有道理的--你正在创建一个等待工作的线程池,它应该是你明确的关闭它的意图。
另一方面,ForkJoinPool将您从底层线程池中抽象出来。因此,它可以使用守护进程线程,因为它通常是您等待任务执行的意图。
发布于 2018-06-10 00:27:51
Rui,你的例子为什么挂起的答案很简单。缺省情况下,ExecutorService中的线程是非守护进程线程,只要有非守护进程线程在运行,Java程序就不会退出。如果您不想要此行为,则只需定义一个创建守护进程线程的ThreadFactory,如下所示:
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"); } });
}
}
https://stackoverflow.com/questions/50754759
复制相似问题