[Fork/Join]在main方法中写Fork/Join测试,main线程结束,ForkJoinPool中的线程为什么也结束了?

Main函数:

public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        List list = new ArrayList();
        for (int i = 0; i < 100; i++) {
                list.add(i);
        }

        TestTask task = new TestTask(list);
        forkJoinPool.invoke(task);

        System.out.println("task 完成:" + task.isDone());
        System.out.println(System.currentTimeMillis() + " - Main: The program has finished");
} 

任务类:

public class TestTask extends RecursiveAction {

    private List list;
    private final int limit = 10;

    public TestTask(List list) {
        this.list = list;
    }

    @Override
    protected void compute() {
        if (list.size() <= limit) {
            System.out.println(System.currentTimeMillis() + " - " + list);
        } else {
            int middle = (list.size()) /2;

            TestTask left = new TestTask(list.subList(0, middle));
            TestTask right = new TestTask(list.subList(middle, list.size()));
            //子任务用了异步
            left.fork();
            right.fork();
        }
    }
}

如果在main函数中,使用execute执行任务,main线程结束,程序就结束了,控制台没有任何的任务输出。

如果在main函数中,使用invoke执行任务,main线程结束,程序没有立即结束,控制台有任务输出,但是任务没有全部执行完成。
这是怎么回事?

1.execute是异步执行(不需要等待task执行完毕主函数就继续执行下面的语句);invoke是同步执行,主函数等待invoke执行完毕再继续执行。
2.主线程是非守护线程,ForkJoinPool执行任务的线程是守护线程。主线程执行execute后没有等task完成就继续执行后续命令然后主线程结束,当程序中只有守护线程时jvm就会退出。
建议主线程执行execute后做判断while(!task.isDone()){System.out.println("任务执行中...");Thread.sleep(1000);}
或者调用invoke,主线程阻塞等待task执行完成