集合类不安全之并发修改异常:java.util.ConcurrentModificationException,高并发多线程访问下的常见异常

ArrayList线程不安全的原因是其中的add方法没有加锁

  1. 故障现象:java.util.ConcurrentModificationException
  2. 导致原因:并发争抢修改导致,参考花名册签名情况,一个人正在写,另一个同学过来抢夺,导致数据不一致异常。并发修改异常。
  3. 解决方案:
    1. 用Vector
    2.  Collections.synchronizedList(new ArrayList<>();
    3.  new CopyOnWriteArrayList<>();

 

 

Set线程不安全问题

       解决方案:

    1.   Collections.synchronizedSet(new ArraySet<>();
    2.  new CopyOnWriteArraySet<>();

HashSet底层数据结构Hash Map,但是Set中填一个值Map中填两个值原因是HashSet的add方法调用HashMap的put方法,但是add方法中添加的值是put中的K,V是一个PRECENT常量

Map线程不安全问题:

       解决方案:

5.1   Collections.synchronizedSet(new HashMap<>();

         5.2 new CopyOnWriteHashMap<>();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`java.util.ConcurrentModificationException`异常通常发生在多线程环境下,当程序试图同时修改一个集合(如List、Set或Map)的内容,而这些集合是被其他线程正在遍历的时候。这是因为Java的集合类内部维护了一个迭代器,这个迭代器假设集合的内容不会改变,但在并发情况下,如果线程A正在遍历,线程B修改了集合,就会导致迭代器无法正确跟踪元素,从而抛出此异常。 要解决这个问题,可以采取以下几种策略: 1. **避免在迭代过程中修改集合**:如果你知道可能会有修改,尽量在遍历之前完成所有可能的修改操作,或者使用不可变集合(如`Collections.unmodifiableList()`)。 2. **同步操作**:如果必须在迭代过程中修改,确保对集合的修改操作是在同步块中进行,这样可以保证同一时间只有一个线程可以修改集合。 3. **使用并发集合**:Java提供了一些并发版本的集合,如`CopyOnWriteArrayList`和`ConcurrentHashMap`,它们在修改时会创建新的视图,避免了直接抛出异常,而是返回一个新的结果。 4. **使用`Iterator.remove()`替换`List.remove()`**:在`List`迭代器上调用`remove()`方法时,不会抛出`ConcurrentModificationException`,但会导致迭代提前结束。 在你给出的代码示例中,删除元素时引发异常是因为尝试在线程安全的迭代中修改了集合结构。正确的做法是先移除元素再迭代,或者在遍历时使用`Iterator.remove()`替换`List.remove()`。 ```java // 错误示例 List<Integer> list = ...; Iterator<Integer> it = list.iterator(); while (it.hasNext()) { if (it.next().equals(3)) { // 不应在迭代过程中修改 it.remove(); // 这里会抛出异常 } } // 正确示例 List<Integer> list = ...; Integer target = 3; list.remove(target); // 先移除元素 for (Integer element : list) { // 现在可以安全地遍历 } ``` [^1]: java.util.ConcurrentModificationException异常原因及解决方法。@TOC 欢迎使用Markdown编辑器 : java.util.ConcurrentModificationException异常原因及解决方法。复制代码 上述代码在删除value=3的元素时,报java.util.ConcurrentModificationException异常,如下图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值