java - Java 8 流 lambda 中的共享可变性
问题描述
据说共享可变性在 Java8 中是邪恶的,我有一个像下面这样的用例,我正在修改 parallelStream() 中的共享列表,只是想知道这是否可以作为例外来获得 parallelStream() 的好处或应该只需使用命令式代码并牺牲并行性。
另外,我们可以使用其他方法来遇到这种情况吗?
private List<CustomClass> perfromActionInStream(Map<Long, List<CustomClass>> longCustomMap) {
List<CustomClass> synchronizedList = Collections.synchronizedList(new ArrayList<>());
longCustomMap
.entrySet()
.parallelStream()
.forEach(entry -> performActionInLambda(synchronizedList, entry));
}
private void performActionInLambda(List<CustomClass> synchronizedList,
Map.Entry<Long, List<CustomClass>> entry) {
try {
Map<Long, CustomClass> recordsFromDb = persistService
.findInDb(entry.getKey());
//Based on some condition
if(recordsFromDb.containsKey(entry.getKey())){
//Some if condition on value for the entry
recordsFromDb.remove(entry.getKey())
}
//:::Shared mutation::::Add all remaining elements from recordsFromDb to synchronizedList
synchronizedList.addAll(recordsFromDb.values());
} catch (DataAccessException e) {
log.error("Error occurred in lambda for fetching records from database", e);
throw e; //throwing to stop further execution
}
}
解决方案
在这种情况下,与其将其作为并行流进行,不如您可以获取映射中所有键的数据库记录(或者,根据映射的大小以块的形式)会更好。这将使数据库调用一次或更少次,从而提高代码的性能。我觉得在 lambda 并行执行中改变一个同步列表可能不是一个好的选择。
推荐阅读
- jenkins - 仅归档 katalon jenkins 作业中的最新 .png 文件
- matlab - 如何在地块上使用刺作为刻度?
- python - 传递给我的自定义模块时 var 类型的 Ansible 错误
- flutter - 如何在颤动的图像中插入可点击点?
- java - 连接spring boot应用程序和google Cloud SQL的推荐方式是什么?
- python - Kivy: UnicodeEncodeError: 'gbk' codec can't encode character '\u017c' in position 256: 非法多字节序列
- api-platform.com - 带有计算列的 Api 平台过滤器(即地理距离)
- javascript - Javascript chai 为什么抛出没有被抓到?
- javascript - Javascript 问题:检查输入框中是否包含单词的脚本。仅全词
- amazon-s3 - AWS Lambda 不会将文件从一个 s3 存储桶复制到云中的另一个存储桶,但在本地它可以工作