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执行完成