【问题标题】:Adding elements in Non-synchronized ArrayList using java parallel stream使用java并行流在非同步ArrayList中添加元素
【发布时间】:2016-04-15 17:57:38
【问题描述】:

我想使用 java 并行流并行运行此代码,并将结果更新为两个 ArrayList。下面给出的代码工作正常,除了 ArrayList 的非线程安全可能导致不正确的结果,我不想同步ArrayList。有人可以建议我在我的情况下使用并行流的正确方法吗?

        List<Integer> passedList= new ArrayList<>();
        List<Integer> failedList= new ArrayList<>();

        Integer[] input = {0,1,2,3,4,5,6,7,8,9};
        List<Integer> myList = Arrays.asList(input);

        myList.parallelStream().forEach(element -> {

            if (isSuccess(element)) {//Some SOAP API call.
                passedList.add(element);
            } else {
                failedList.add(element);
            }

        });
        System.out.println(passedList);
        System.out.println(failedList);

【问题讨论】:

  • CompletableFuture 在这里可能更合适

标签: java multithreading arraylist parallel-processing java-stream


【解决方案1】:

一个合适的解决方案是使用Collectors.partitioningBy:

Integer[] input = {0,1,2,3,4,5,6,7,8,9};
List<Integer> myList = Arrays.asList(input);

Map<Boolean, List<Integer>> map = myList.parallelStream()
        .collect(Collectors.partitioningBy(element -> isSuccess(element)));

List<Integer> passedList = map.get(true);
List<Integer> failedList = map.get(false);

这样你就不会有线程安全问题,因为任务将以 map-reduce 方式分解:输入的部分将被独立处理并在之后加入。如果您的 isSuccess 方法很慢,您可能会在此处获得性能提升。

顺便说一句,您可以使用 Arrays.stream(input).parallel() 从原始数组创建并行流,而无需创建中间 myList

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 2014-04-08
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    相关资源
    最近更新 更多