java并行流下集合线程安全和线程并发修改问题

最近工作中有个需求是这样的:将postgresql中的字段取出来,这个字段是以jsonb数组存储的,使用java将它转换为JSONArray后,需要将其中每个对象中属性值中包含空字符串的替换为下划线。
因为JSONArray实现了List接口,因此直接使用了parallelStream.foreach遍历。看了结果,发现有的属性中包含空字符串的并没有替换成下划线。debug后发现并行环境下,出现了线程安全问题。
然后把parallelStream去掉,但是因为在遍历过程中对集合进行了remove和add操作,会抛出并发修改异常。使用迭代器iterator遍历也不行,虽然可以实行迭代器的remove,但是add操作还是在原来集合上。
最后没有办法,只能使用CopyOnWriteArrayList这个并发容器,它适用于读多写少的场景。但我看了业务,发现写的场景也很多,但是不使用它的话,那么就需要在对集合remove和add时手动进行加锁,比如使用parallelStream.foreach的方式,然后在里面进行写的时候加锁,但是总感觉这样有点滑稽,在并行流里加锁。。。
最后贴个部分代码

       CopyOnWriteArrayList<Object> copyOnWriteArrayList = new CopyOnWriteArrayList<>(valueArray);
        copyOnWriteArrayList.forEach(v -> {
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(v));
            if (jsonObject.containsKey("indicator") && jsonObject.get("indicator") != null) {
                String indicator = JSON.toJSONString(jsonObject.get("indicator"));
                if (indicator.contains(" ")) {
                    copyOnWriteArrayList.remove(v);
                    String replace = indicator.replace(" ", "_");
                    jsonObject.remove("indicator");
                    jsonObject.put("indicator", replace);
                    copyOnWriteArrayList.add(jsonObject);
                }
            }
        });
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值