由于RaceCondtion

时间:2019-02-04 05:51:02

标签: java java-8 linked-list java-stream parallel.foreach

我们正在使用java8中的Streams迭代LinkedList,并创建另一个列表。但是由于比赛条件,结果列表大小变长了。

List<DesInfo> InfoList = new LinkedList<>();
documentList.stream()
            .parallel()
            .forEach(document -> {
                Info descriptiveInfo = objectFactory.createDescriptiveInfo();
                List<Document> documents = new ArrayList<>();
                documents.add(document);
                descriptiveInfo.setHotelInfo(getHotelInfo(document.get(CODE), documents));
                InfoList.add(Info);
            });

如果每次我们都运行此代码,我们将看到为同一documentList输入生成的InfoList大小不同。我浏览了一些论坛,他们提到像LinkedList不是线程安全的,而是去了任何线程安全的集合。但是我的要求不允许我除LinkedList之外进行更改。我需要对相同的LinkedList使用并行流功能。

谢谢, 拉加万

2 个答案:

答案 0 :(得分:2)

使用time=[1,2,3,4,5,6] cost=[4,5,3,4,8,9] var_matrix=np.array([time,cost]).T mean = np.mean(var_matrix,axis=0) sigma = np.cov(var_matrix.T) y = multivariate_normal.pdf(var_matrix, mean=mean, cov=sigma,allow_singular=True) forEach操作代替使用Collector

map()

List<HotelDescriptiveInfo> hotelDescriptiveInfoList = documentList.parallelStream() .map(document -> { HotelDescriptiveInfo descriptiveInfo = objectFactory.createHotelDescriptiveInfo(); List<Document> documents = new ArrayList<>(); documents.add(document); descriptiveInfo.setHotelInfo(getHotelInfo(document.get(HOTEL_CODE), documents)); return descriptiveInfo; }) .collect(Collectors.toCollection(LinkedList::new)); API将负责处理,并且不允许出现竞争情况。

答案 1 :(得分:2)

使用collect而不是更改集合的状态。

首先创建一个映射函数:

private DesInfo documentToDesInfo(Document document){
    DesInfo info = objectFactory.createDescriptiveInfo();
    List<Document> documents = new ArrayList<>();
    documents.add(document);
    info.setHotelInfo(getHotelInfo(document.get(CODE), documents));
    return info;
}

然后在您的管道中使用它:

List<DesInfo> infoList = documentList.parallelStream()
                                     .map(this::documentToDesInfo)
                                     .collect(toCollection(LinkedList::new));