java 8并行流混淆/问题

use*_*3 ツ 2 java java-8 java-stream

我是并行流的新手,并试图制作一个计算值*100(1到100)并将其存储在地图中的示例程序.在执行代码时,每次迭代都会有不同的数量.我可能在某个地方错了所以请指导我,任何人都知道正确的方法.

代码:

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.stream.Collectors;

public class Main{    
    static int l = 0;       
    public static void main (String[] args) throws java.lang.Exception {
        letsGoParallel();
    }       
    public static int makeSomeMagic(int data) {
        l++;
        return data * 100;
    }        
    public static void letsGoParallel() {
        List<Integer> dataList = new ArrayList<>();
        for(int i = 1; i <= 100 ; i++) {
            dataList.add(i);
        }
        Map<Integer, Integer> resultMap = new HashMap<>();
        dataList.parallelStream().map(f -> {
            Integer xx = 0;
            {
                xx = makeSomeMagic(f);
            }
            resultMap.put(f, xx);
            return 0;
        }).collect(Collectors.toList());
        System.out.println("Input Size: " + dataList.size());
        System.out.println("Size: " + resultMap.size());
        System.out.println("Function Called: " + l);
    }
}
Run Code Online (Sandbox Code Playgroud)

可运行代码

最后输出

输入大小:100

尺寸:100

功能称为:98

每次运行输出都不同.我想在我自己的应用程序中使用并行流,但由于这种混淆/问题我不能.在我的应用程序中,我有100-200个唯一编号,需要执行相同的操作.简而言之,它有处理某些东西的功能.

Era*_*ran 5

HashMapl变量和变量的访问都不是线程安全的,这就是每次运行时输出不同的原因.

做你想做的事的正确方法是将Stream元素收集到Map:

Map<Integer, Integer> resultMap =
    dataList.parallelStream()
            .collect(Collectors.toMap (Function.identity (), Main::makeSomeMagic));
Run Code Online (Sandbox Code Playgroud)

编辑:使用此代码l仍然以线程安全的方式更新变量,因此如果变量的最终值对您很重要,则必须添加自己的线程安全性.