在完成所有线程之前从java方法返回

是否可以在完成所有线程之前从启动线程的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).

上一篇:Java ThreadFactory的问题


下一篇:什么是Java线程池RejectedExecutionHandler中传递的可运行对象