在Java 8中使用并行流时,我得到了相同请求的不同大小的响应。任何人都可以提供有关如何处理此问题的见解吗?

问题描述 投票:3回答:2

我的应用程序结构如下:一个控制器,它调用一个服务类,该服务类又调用一个存储库类。存储库(objectRepo)返回对象列表。服务类通过它从存储库获取的对象列表进行解析,并将其转换为apiResponseWrapper类。控制器将此apiResponseWrapper提供给用户而不更改它。

在我的Service类中,我的代码可以有效地转换为以下示例代码:

List<Object> objectList = objectRepo.getList(paramMap);
List<Entity> entityList = new ArrayList<>();
objectList.parallelStream().forEach(object->{
//code to transform object
entityList.add(transformedObject);
});
return entityList;

当像上面一样使用parallelstream时,我的API响应的大小在连续调用时会有所不同,参数完全相同,并且在进一步检查时,某些实体在少数这些调用的响应中不存在。在删除parallelStream时,响应的大小保持不变,并且所有预期的实体都在结果中。

我想知道是否有任何特定方式/任何一套指导方针可以帮助我使用parallelstream而不丢弃任何数据。

java lambda java-8
2个回答
4
投票

不要这样做......使用:

List<Entity> entityList = objectList.stream()
          .parallel()
          .map(object -> transform to transformedObject)
          .collect(Collectors.toList())

毕竟entityList不是从多个线程更新的线程安全集合,因此在文档中也不鼓励这是不需要的副作用。

此外,很少有parallel可以提高性能的情况,你需要很多对象才能产生任何有意义的效果。


1
投票

这是在调整你的构造工作。正确的做法是@Eugene说的。

您不能在并行上下文中使用非线程安全列表。使用线程安全结构作为SynchroneusQueue或替代ad adroneus块。

List<Object> objectList = objectRepo.getList(paramMap);
SynchroneusQueue<Entity> entityList = new SynchroneusQueue<>();
objectList.parallelStream().forEach(object->{
//code to transform object
entityList.add(transformedObject);
});
return entityList;

这或多或少等同于:

List<Object> objectList = objectRepo.getList(paramMap);
List<Entity> entityList = new ArrayList<>();
objectList.parallelStream().forEach(object->{
//code to transform object
synchronized(entityList) {
    entityList.add(transformedObject);
}
});
return entityList;
© www.soinside.com 2019 - 2024. All rights reserved.