【问题标题】:Second parallel streams starts before completing the first第二个并行流在完成第一个之前开始
【发布时间】:2019-01-25 05:52:21
【问题描述】:
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Main {

    public static void main(String[] args) {
        List<Integer> fullList = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
        List<Integer> toBeLast = Arrays.asList(9,10,11,12);
        Random r = new Random();

        fullList.parallelStream().filter(l->!toBeLast .contains(l)).forEach(l->{
        System.out.println("L1 : " + e);
            try {

                Thread.sleep(Math.abs(r.nextLong() % 1000));
                    System.out.println(l);
            }
            catch(InterruptedException i) {

            }
        });

        toBeLast .parallelStream().forEach(l->{
            System.out.println("L2 : " + e);
                try {

                    Thread.sleep(Math.abs(r.nextLong() % 1000));
                    System.out.println(l);
                }
                catch(InterruptedException i) {

                }
        });

    }
}

期望 - 完成 1-8、13-14 并开始 9-12。

其余调用将在服务器中触发一个 sh 脚本,每个脚本需要 15-90 秒。 实际 - 在服务器中,有一次我看到 2 和 11 的脚本正在运行。我还没有看到 2 的 sysout,服务器和程序也不例外。

我想知道怎么可能在完成 2 之前触发 11?

【问题讨论】:

  • l1 和 l2 是分离的?那是在 l1 中没有价值,在 l2 中也是如此?
  • 你需要join线程..你可以使用CompletableFuture或者Executors
  • 按照当前答案中的建议,尝试用一些简单的日志输出替换对 REST 端点的实际调用,看看是否还有这个问题。鉴于您当前的代码,没有迹象表明有任何问题。
  • 我没有发现任何问题。它将按您的预期处理(打印)......它不会在 2 之前处理 11。其他肯定是错误的
  • 您更新的代码仍然可以。 l1 中的所有元素将在 l2 中的元素之前处理。如何调用 sh 脚本以及脚本的外观如何?问题可能出在那儿。

标签: java parallel-processing java-stream


【解决方案1】:

问题中有些地方不对劲。这是我编写的代码,在我的示例中,第一个流总是在第二个流之前完成。

import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Main {

    public static void main(String[] args) {

        List<Integer> l1 = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,1,2,3,4,5,6,7,8,9,10,11,12,13,14,1,2,3,4,5,6,7,8,9,10,11,12,13,14,1,2,3,4,5,6,7,8,9,10,11,12,13,14);
        List<Integer> l2 = Arrays.asList(21,22,23,24,25,26,27,28,29,30,31,32,33,34,21,22,23,24,25,26,27,28,29,30,31,32,33,34,21,22,23,24,25,26,27,28,29,30,31,32,33,34,21,22,23,24,25,26,27,28,29,30,31,32,33,34);
        Random r = new Random();

        l1.parallelStream().forEach(e -> {
            System.out.println("L1 : " + e);
            try {

                Thread.sleep(Math.abs(r.nextLong() % 1000));
            }
            catch(InterruptedException i) {

            }
        });
        l2.parallelStream().forEach(e -> {
            System.out.println("L2 : " + e);
            try {

                Thread.sleep(Math.abs(r.nextLong() % 1000));
            }
            catch(InterruptedException i) {

            }
        });
    }
}

我的猜测是您正在使用在后台执行活动的 HTTP 客户端库,因此第二个流在第一个流完成之前就开始了。

【讨论】:

  • 谢谢。我修改了代码以更多地反映我的确切情况。想知道我错过了什么。
猜你喜欢
  • 1970-01-01
  • 2016-12-13
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多