假设我必须并行运行一些(大部分是独立的)昂贵的任务。通常,这可以使用 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 方法中的一个。自然地,我不想通过一长串方法调用或使用全局变量将其作为参数传递。理想情况下,我想将我的程序限制为父池使用的线程数,而不做任何此类技巧。