众所周知,java.util.concurrent.Executors
包含许多方法,例如
newCachedThreadPool
newFixedThreadPool
newScheduledThreadPool
newSingleThreadExecutor
newSingleThreadScheduledExecutor
他们返回ExecutorService
,其中包含execute(Runnable task)
方法。但是,在调用从上述工厂方法返回的execute(Runnable task)
ExecutorService
时,只能通过调用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()
所以我的问题是:为什么execute()
的{{1}}从上述工厂方法返回,以“new”开头“如果不从设计角度调用ExecutorService
或shutdown()
,则不会终止?
答案 0 :(得分:0)
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"); } });
}
}
答案 1 :(得分:0)
简要介绍一下java线程:有两种类型的线程 - 守护进程和非守护进程。程序在其所有非守护程序线程都已完成执行时终止。守护程序线程只能在程序运行的时间内运行,并且不会阻止终止,例如garbage collector。当一个java程序启动它的所有线程,除了主线程是守护进程。
newSingleThreadExecutor()
及其defaultThreadFactory()
创建非守护程序线程。哪种方式有意义 - 您正在创建一个等待工作的线程池,应该是您明确意图将其关闭。