是否可以在完成所有线程之前从启动线程的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;
}
}
由于我不理解的某些原因,这不会返回.为什么主线程的返回受到工作线程卡住的影响?
解决方法:
您的主要方法是返回,但问题是您的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
>在ExecutorService上使用shutdownNow()
.这将在每个正在运行的线程上发送一个中断.您仍然需要在每个线程上检查,通过调用抛出InterruptedException的方法或通过显式调用Thread.currentThread().isInterrupted().
对于shutdownNow方法,请注意,中断线程本身并不足以阻止它 – 在该线程上运行的代码必须通过检查其中断状态(使用这两种方法之一)并适当退出来进行协作.例如,你可以用while(!Thread.currentThread().isInterrupted())替换while(true).