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