当前位置: 首页 > 知识库问答 >
问题:

使用Java 8流最大化并行性[重复]

夏高朗
2023-03-14

请考虑下面的代码。我希望这10个任务中的每一个同时运行100毫秒。

long runUntil = System.currentTimeMillis() + 100;
IntStream.range(0, 10).parallel().forEach(i ->
{
    int cnt = 0;
    while(System.currentTimeMillis() < runUntil)
        cnt++;
    System.out.println(i + ": " + cnt);
});

然而,我得到的结果是:

2: 56443
1: 67506
4: 74693
6: 70549
0: 0
3: 0
5: 0
7: 0
8: 0
9: 0

所以只有4个任务并行执行,第五个任务只有在前4个任务中的一个完成时才开始。我希望所有的任务都差不多同时开始,而不是彼此等待。

我不同意它是Java8Parallel stream中自定义线程池的重复,因为问题是运行缓慢的任务阻塞了其他任务,而在我的例子中,我只是想知道在使用stream API时如何(如果可以的话)最大化并行性。

共有1个答案

辛建业
2023-03-14

当您执行并行流时,您正在调用ForkJoinPool,该池的工作线程数等于以下结果:

 Runtime.getRuntime().availableProcessors(); // 4 in your case

因此并行任务由4个线程并发执行。

在您开始第5个任务时(100毫秒已过),因此此条件:

  while(System.currentTimeMillis() < runUntil)
long runUntil = System.currentTimeMillis() + 1000;
ForkJoinPool forkJoinPool = new ForkJoinPool(10); // 10 Threads
forkJoinPool.submit(() ->
IntStream.range(0, 10).parallel().forEach(i -> {
    int cnt = 0;
    while (System.currentTimeMillis() < runUntil)
        cnt++;
    System.out.println(i + ": " + cnt);
})).get();
 类似资料:
  • 我想用Java8lambda表达式在java列表中找到max值,所以,我有一个类叫TicketMaster,项表是TicketMasterLog,在TicketMasterLog类中我有StatusMaster类的statusId引用列,所以这里我想在TicketMasterLog列表中找到max statusId,下面我给出我的代码请参考 而TicketMasterItem表是 因此,在列表中,

  • 它们之间有什么相同和不同之处,看起来Java并行流中有RXJava中可用的一些元素,是吗?

  • 阅读Java8的并行流API:https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html 还不清楚在使用这个流式API的并行性时,如何调优要使用的线程数? 计划在一个非常特定的机器类型和一致的数据类型上运行它,所以我想我可以在一组不同的设置上对它进行基准测试,然后使用最佳数量的线程。

  • 我认为流API在这里是为了使代码更易于阅读。我觉得有点烦。流接口扩展了java。lang.AutoCloseable接口。 因此,如果你想正确地关闭流,你必须使用try-with资源。 清单1.不是很好,流没有关闭。 清单2.使用2嵌套try 清单3。当map返回流时,必须关闭stream()和map()函数。 我举的例子毫无意义。为了示例,我将jpg图像的路径替换为整数。但不要让这些细节分散你的