我的应用程序结构如下:一个控制器,它调用一个服务类,该服务类又调用一个存储库类。存储库(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而不丢弃任何数据。
不要这样做......使用:
List<Entity> entityList = objectList.stream()
.parallel()
.map(object -> transform to transformedObject)
.collect(Collectors.toList())
毕竟entityList
不是从多个线程更新的线程安全集合,因此在文档中也不鼓励这是不需要的副作用。
此外,很少有parallel
可以提高性能的情况,你需要很多对象才能产生任何有意义的效果。
这是在调整你的构造工作。正确的做法是@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;