0

假设我必须并行运行一些(大部分是独立的)昂贵的任务。通常,这可以使用 fork/join 框架轻松完成。

我的问题是,其中一些任务也可能产生子任务,使用不同的 ForkJoinPool (在调用层次结构更深的某些方法中)。我知道这会产生许多线程,这可能会减慢我的应用程序,我想避免这种情况。一种解决方案是使用全局池并在那里添加任务,但这不是我的选择。

这对我有用的原因是一些原始任务是依赖的并且可能相互等待。例如,假设 A1 和 A2 是两个任务,需要 B 的结果(可并行化)才能分别进行到 C1 和 C2。在这种情况下,运行 A1 和 A2 的线程可以专注于 B 以提高 CPU 利用率。一个简单的例子如下所示。

ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();

public int expensiveComputation(int x) {
    int result = x;
    // do stuff using different ForkJoinPool!
    return result;
}

public abstract class A {
    public abstract run(int x);
}

public class A1 extends A {

    public A1(int x) {
        super(x);
    }

    @Override
    public void run() {
        // do stuff
        // Only 1 thread will run this for a given value of x
        map.putIfAbsent(x, expensiveComputation(x));
        // do stuff
    }
}

public class A2 extends A {

    public A2(int x) {
        super(x);
    }

    @Override
    public void run() {
        // do stuff
        // Only 1 thread will run this for a given value of x
        map.putIfAbsent(x, expensiveComputation(x));
        // do stuff
    }
}

public static void main(String[] args) {
    LinkedList<A> tasks = new LinkedList<>();
    tasks.add(new A1(0));
    tasks.add(new A2(0));
    // More tasks

    ForkJoinPool pool = new ForkJoinPool(parallelism);
    pool.submit(() -> tasks.parallelStream().forEach((x -> {
        x.run();
    })));
}

是否可以在这些任务中使用“父”池?在上面的示例中,父池是 main 方法中的一个。自然地,我不想通过一长串方法调用或使用全局变量将其作为参数传递。理想情况下,我想将我的程序限制为父池使用的线程数,而不做任何此类技巧。

4

0 回答 0