【问题标题】:ForkJoinPool creating thouthands of threadsForkJoinPool 创建数以千计的线程
【发布时间】:2013-09-10 14:59:51
【问题描述】:

一个演示问题的简单测试:

package com.test;

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

public class Main extends RecursiveTask<Long> {
    private volatile long start;
    private volatile long end;
    private volatile int deep;

    public Main(long start, long end, int index, int deep) {
        this.start = start;
        this.end = end;
        this.deep = deep;
//        System.out.println(deep + "-" + index);
    }

    @Override
    protected Long compute() {
        long part = (end - start) / 10;
        if (part > 1000 && deep < 10) {
            List<RecursiveTask<Long>> subtasks = new ArrayList<RecursiveTask<Long>>();
            for (int i = 0; i < 10; i++) {
                long subtaskEnd = start + part;
                if (i == 9) {
                    subtaskEnd = end;
                }
                subtasks.add(new Main(start, subtaskEnd, i, deep + 1));
                start = subtaskEnd;
            }

            //CASE 1: generates 3000+ threads
            for (int i = 0; i < 10; i++) {
                subtasks.get(i).fork();
            }

            //CASE 2: generates 4 threads
//            invokeAll(subtasks);

            //CASE 3: generates 4 threads
//            for (int i = 9; i >= 0; i--) {
//                subtasks.get(i).fork();
//            }


            long count = 0;
            for (int i = 0; i < 10; i++) {
                count += subtasks.get(i).join();
            }
            return count;
        } else {
            long startStart = start;
            while (start < end) {
                start += 1;
            }
            return start - startStart;
        }
    }

    private static ForkJoinPool executor = new ForkJoinPool();

    public static void main(String[] args) throws Exception {
        ForkJoinTask<Long> forkJoinTask = executor.submit(new Main(0, Integer.MAX_VALUE / 10, 0, 0));

        Long result = forkJoinTask.get();
        System.out.println("Final result: " + result);
        System.out.println("Number of threads: " + executor.getPoolSize());
    }

}

在这个示例中,我创建了 RecursiveTask,它简单地计算数字以在 CPU 上产生一些负载。它将传入范围递归地划分为 10 个部分,当部分的大小小于 1000 或递归“深度”超过 10 时,它开始计算数字。

compute() 方法中注释了 3 个案例。区别仅在于分叉子任务的顺序。根据我分叉子任务的顺序,最终的线程数是不同的。在我的系统上,它为第一种情况创建 3000 多个线程,为第二种和第三种情况创建 4 个线程。

问题是:有什么区别?我真的需要了解这个框架的内部结构才能成功使用它吗?

【问题讨论】:

    标签: java multithreading parallel-processing fork-join


    【解决方案1】:

    这是我在 2011 年的一篇文章中解决的一个老问题,A Java Fork-Join Calamity 该文章指向显示修复的第二部分?为此在 Java8 中(替换停顿而不是额外的线程。)

    你真的不能用这个框架做很多专业的事情。您还可以使用其他框架。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2020-01-02
      • 1970-01-01
      • 2014-02-14
      相关资源
      最近更新 更多