gpt4 book ai didi

java - 自定义 ForkJoinPool 中的嵌套 ArrayList.ParallelStream() 使用线程不均匀

转载 作者:行者123 更新时间:2023-12-03 13:08:24 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Why does stream parallel() not use all available threads?

(2 个回答)


2年前关闭。




我想使用我的自定义 ForkJoinPool 与 ArrayList.parallelStream() 具有更多的并行性(默认情况下它使用公共(public)池)。

我这样做:

List<String> activities = new ArrayList<>();

for (int i = 0; i < 3000; i++) {
activities.add(String.valueOf(i));
}

ForkJoinPool pool = new ForkJoinPool(10);
pool.submit(() ->
activities.parallelStream()
.map(s -> {
try {
System.out.println("Start task = " + s);
Thread.sleep(100);
System.out.println("End task = " + s);
} catch (InterruptedException e) {
e.printStackTrace();
}
return s;
})
.collect(toList())
).get();

当我观察 VisualVM 中的工作方式时,我看到:
VisualVM with parallelism 10

在某些时候,一些线程被停放,而其他线程完成其余的工作。当我查看转储时,我看到什么都不做的线程处于停放状态。

实验表明,如果您创建一个具有并行参数的 ForkJoinPool 是 2 的幂,则一切正常......
List<String> activities = new ArrayList<>();

for (int i = 0; i < 3000; i++) {
activities.add(String.valueOf(i));
}

ForkJoinPool pool = new ForkJoinPool(16);
pool.submit(() ->
activities.parallelStream()
.map(s -> {
try {
System.out.println("Start task = " + s);
Thread.sleep(100);
System.out.println("End task = " + s);
} catch (InterruptedException e) {
e.printStackTrace();
}
return s;
})
.collect(toList())
).get();

VisualVM with parallelism 8

它可以是任何小于 64 的 2 的幂(我不知道为什么,但它不超过 ForkJoinPool 的 34 个线程),但如果它不是 2 的幂,我们会得到奇怪的行为。

为什么会发生?如何使用它?

最佳答案

您应该调用工厂方法 ForJoinPool.commonPool(),而不是实例化您自己的 ForkJoinPool。这应该与您可用的核心相适应。

你能不能试一试。

无论如何,我认为你最好使用 Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())反而。

关于java - 自定义 ForkJoinPool 中的嵌套 ArrayList.ParallelStream() 使用线程不均匀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49068119/

25 4 0