是否有可能在所有线程完成之前从启动线程的java方法返回?
这是我的代码:
import java.util.concurrent.*;
public class ExecutorSample {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
service.execute(() -> {
while (true) {
}
});
}
return;
}
}
由于某种我不了解的原因而无法返回。为什么主线程的返回会受到工作线程卡住的影响?
答案 0 :(得分:5)
您的main
方法正在返回,但是问题在于您的JVM没有退出。您可以通过将main
方法重命名为doMain()
之类的其他方法,然后将main
编写为:
public static void main(String[] args) {
doMain();
System.out.printf("here");
}
您会看到确实得到了输出,但是程序没有结束。
正在发生的事情是Executors.newCachedThreadPool
使用default thread factory,它创建了非守护线程。当您的main
方法返回时,JVM将等待所有非守护程序线程完成(这是它们与守护程序线程的区别-JVM不等待那些线程)。由于您所有的Runnable都将永远运行,因此非守护进程线程将永远不会完成,并且JVM将永远不会退出。
你能做什么?一些选项:
newCachedThreadPool(ThreadFactory)
,提供一个创建守护程序线程的ThreadFactory shutdownNow()
。这将在每个正在运行的线程上发送一个中断。您仍然必须在每个线程上进行检查,方法是调用引发InterruptedException
的方法或显式调用Thread.currentThread().isInterrupted()
。对于shutdownNow
方法,请注意,仅中断线程本身不足以停止该线程-在该线程上运行的代码必须通过检查其中断状态来配合(使用这两种方法之一)并适当退出。例如,您可以将while(true)
替换为while (!Thread.currentThread().isInterrupted())
。