【问题标题】:Parallel stream doesn't look like working in parallel, completely并行流看起来不像完全并行工作
【发布时间】:2019-04-12 02:30:09
【问题描述】:

1。 Set 的 parallelStream 没有使用足够的线程。

Java8 parallelStream 不能完全并行工作。 在我的电脑中,当任务的数量小于处理器的数量时,java8 set的parallelStream没有使用足够的线程。

public class ParallelStreamSplitTest {
    @Test
    public void setStreamParallelTest() {
        System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
        long start = System.currentTimeMillis();
        IntStream.range(1, 8).boxed().collect(Collectors.toCollection(HashSet::new)).parallelStream().forEach((index) -> {
            System.out.println("Starting " + Thread.currentThread().getName() + ",    index=" + index + ", " + new Date());
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
        });
        long end = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
    }

    @Test
    public void intStreamParallelTest() {
        System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
        long start = System.currentTimeMillis();
        IntStream.range(1, 8).parallel().forEach(index -> {
            System.out.println("Starting " + Thread.currentThread().getName() + ",    index=" + index + ", " + new Date());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        });
        long end = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
    }
}

在我的代码中,setStreamParallelTest 需要 4 秒,而 intStreamParallelTest 需要 1 秒。

我希望 setStreamParallelTest 也能在 1 秒内完成。 是bug吗?

2。可以使用并行流在 Web 应用程序中调用另一个 api 吗?如果是错的,为什么?

我的 Web 应用程序需要并行调用另一个 api 服务器。所以我使用并行流来调用api。

Sets.newHashSet(api1, api2, api3, api4).parallelStream().forEach(api -> callApiSync(api))

我认为所有发往我的服务器的请求共享一个 fork-join 池。所以,当其中一个 api 的响应很慢时,它看起来很危险。

对吗?

【问题讨论】:

  • “setStreamParallelTest 需要 4 秒”“我希望 setStreamParallelTest 也能在 4 秒内完成”?啊?!?如果您期望 4 并且需要 4,那么问题出在哪里?
  • 什么是Sets? --- HashSet.parallelStream() 不接受任何参数。你的意思是parallelStream().forEach(api -> callApiSync(api))
  • 使用System.currentTimeMillis() 进行基准测试存在严重缺陷。由于多种原因,您无法从这种基准测试中得出任何有意义的结论。
  • 仅供参考: new HashSet<>(IntStream.range(1, 8).mapToObj(i -> new Integer(i)).collect(Collectors.toList())) 最好写成 IntStream.range(1, 8).boxed().collect(Collectors.toCollection(HashSet::new))
  • @Andreas 抱歉。是错字。我预计 1 秒。

标签: java java-stream


【解决方案1】:

parallelStream 的合同说:

返回一个可能并行的流,该集合作为其源。此方法允许返回顺序流。

如果您想并行调用多个任务,请使用ExecutorService

【讨论】:

  • 但是......请注意,ExecutorService 的并行性受到线程池大小的限制。在实践中,取决于 JVM 可用的内核数量、时间切片和其他因素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多