Java 最终结果从未出现

Java 最终结果从未出现,java,forkjoinpool,Java,Forkjoinpool,您好,我是Java并发新手,我正在尝试通过fork-join将列表内容加倍,并将任务划分为多个部分。 任务已完成,但结果从未到达 package com.learning; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; import java.util.concurren

您好,我是Java并发新手,我正在尝试通过fork-join将列表内容加倍,并将任务划分为多个部分。 任务已完成,但结果从未到达

package com.learning;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

class DoubleNumbers extends RecursiveTask<List<Integer>> {
    private final List<Integer> listToDo;
    public DoubleNumbers(List<Integer> list) {
        System.out.println("Cons Called"+list.get(0));
        this.listToDo = list;
    }

    @Override
    protected List<Integer> compute() {
        List<DoubleNumbers> doubleNumbersList= new ArrayList<>();
        System.out.println(Thread.currentThread().toString());
        for (int i = 0; i < listToDo.size(); i++) {
            listToDo.set(i, listToDo.get(i) * 2);
        }
        return listToDo;
    }
}

public class FJPExample {
    public static void main(String[] args) {
        List<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < 149; i++) {
            arrayList.add(i, i);
        }
        ForkJoinPool forkJoinPool = new ForkJoinPool(4);

        System.out.println(forkJoinPool.getParallelism());
        DoubleNumbers doubleNumbers = new DoubleNumbers(arrayList.subList(0, 49));
        DoubleNumbers doubleNumbers50ToNext = new DoubleNumbers(arrayList.subList(50, 99));
        DoubleNumbers doubleNumbers100ToNext = new DoubleNumbers(arrayList.subList(100, 149));
        forkJoinPool.submit(doubleNumbers);
        forkJoinPool.execute(doubleNumbers50ToNext);
        forkJoinPool.execute(doubleNumbers100ToNext);
        do {
            System.out.println("Parallel " + forkJoinPool.getParallelism());
            System.out.println("isWorking" + forkJoinPool.getRunningThreadCount());
            System.out.println("isQSubmission" + forkJoinPool.getQueuedSubmissionCount());
            try {
                TimeUnit.SECONDS.sleep(1000);
            } catch (InterruptedException e) {
                //
            }
        } while ((!doubleNumbers.isDone()) || (!doubleNumbers50ToNext.isDone()) || (!doubleNumbers100ToNext.isDone()));
        forkJoinPool.shutdown(); // Line 56

        arrayList.addAll(doubleNumbers.join());  
        arrayList.addAll(doubleNumbers50ToNext.join());
        arrayList.addAll(doubleNumbers100ToNext.join());
        System.out.println(arrayList.size());
        arrayList.forEach(System.out::println);
    }
}
package.com.learning;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.ForkJoinPool;
导入java.util.concurrent.RecursiveTask;
导入java.util.concurrent.TimeUnit;
类DoubleNumber扩展了RecursiveTask{
私人最终名单;
公众双倍号码(列表){
System.out.println(“Cons调用”+list.get(0));
this.listToDo=list;
}
@凌驾
受保护列表计算(){
List doubleNumbersList=新建ArrayList();
System.out.println(Thread.currentThread().toString());
对于(int i=0;i

如果我调试我的任务,那么我可以发现数字会加倍,但结果从未到达第56行

问题在于代码
arrayList.addAll(doubleNumbers.join())
,第54、55和56行,因为这可能会导致ConcurrentModificationException。因此,您可以做的是,将这些行替换为下面的行,它将起作用(这将起作用,因为您在第36行使用了arrayList.subList,它由同一arrayList支持,请阅读其javadoc以了解更多信息)


这不是
ForkJoinPool
的用途;所有的管理工作都由你来做。您要做的是实现一个
forkjointtask
,它本身进行工作拆分,然后相应地进行分叉和连接。需要注意的是,既然你说你是Java并发新手,那么在进入
ForkJoinPool
(我个人从未使用过,也没有真正了解tbh的意义)之前,先挂上
ExecutorService
s和
CompletableFuture
s会更值得一试。@daniu如果我不得不使用forkjoin将数字翻倍怎么办。还有别的办法吗
doubleNumbers.join();
doubleNumbers50ToNext.join();
doubleNumbers100ToNext.join();