【问题标题】:Why parallelStream() starts at specific point most of the times?为什么 parallelStream() 大部分时间都在特定点开始?
【发布时间】:2021-07-18 08:39:27
【问题描述】:

我有以下代码使用并行流打印列表的元素:

List<Integer> l = List.of(0,1,2,3,4,5,6,7,8,9);
for (int j = 0; j < 5; j++) {
    l.parallelStream().forEach(i->System.out.print(i+" "));
    System.out.println();
}

输出:

6 5 2 8 4 3 9 7 0 1 
6 5 8 9 2 7 4 1 0 3 
6 5 8 9 7 2 4 3 0 1 
6 5 8 9 7 1 0 4 3 2 
6 5 1 0 4 3 2 9 7 8 

为什么并行流大部分时间从6 开始?
为什么不从0 开始?为什么不在中间?

【问题讨论】:

  • 你有多少个cpu核心?
  • 竞争条件有时就是这样产生的。 --- 你为什么会期待“中”?你相信它只做2个线程吗?如果它只将列表分成 2 个块,那么0,1,2,3,4 将始终按该顺序出现,因为线程将按顺序处理子列表。事实例如0,1 有时是 1,0 表示这两个值是由不同的线程打印的,即该代码可能运行 10 个线程。您可以打印线程名称以自己查看使用了多少线程:forEach(i-&gt;System.out.print(i+"("+Thread.currentThread().getName()+") "))
  • @Arthurofos Runtime.getRuntime().availableProcessors() 返回 4。@Andreas 我认为该列表正在拆分,因此大多数情况下它以 6 开头。可能是因为spliterator?

标签: java java-stream parallelstream


【解决方案1】:

列表正在拆分,处理开始使用公共池中的线程。更改代码以打印当前线程名称表明主调用线程也从拆分列表中处理,并且它的结果通常出现在公共池线程之前 - 大概是因为在公共线程开始处理第一个条目之前有一个小的延迟:

List<Integer> l = List.of(0,1,2,3,4,5,6,7,8,9);
for (int j = 0; j < 5; j++) {
    l.parallelStream().forEach(i->System.out.println(Thread.currentThread()+" i="+i));
    System.out.println();
}

在我的机器上,所有输出首先来自主线程:

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[main,5,main] i=7
Thread[main,5,main] i=2
Thread[main,5,main] i=4
Thread[main,5,main] i=3
Thread[main,5,main] i=1
Thread[main,5,main] i=0

但在随后的运行中,工作与公共池更加平衡:

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[main,5,main] i=7
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=2
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=4
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=3
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=1
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=0

Thread[main,5,main] i=6
Thread[main,5,main] i=5
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=2
Thread[main,5,main] i=8
Thread[main,5,main] i=9
Thread[ForkJoinPool.commonPool-worker-7,5,main] i=1
Thread[ForkJoinPool.commonPool-worker-7,5,main] i=0
Thread[main,5,main] i=7
Thread[ForkJoinPool.commonPool-worker-5,5,main] i=4
Thread[ForkJoinPool.commonPool-worker-3,5,main] i=3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-27
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多