ConcurrentModificationException 异常处理

📅 2026/7/17 12:23:27
ConcurrentModificationException 异常处理
java.util.ConcurrentModificationException 异常处理问题背景问题分析解决方案使用迭代器的 remove 方法使用 Collections.synchronizedList使用 CopyOnWriteArrayList创建不可变视图使用并发集合总结问题背景有一个WebSocket利用ConcurrentHashMapInteger, ListPerformWebSocket保存所有在线的长连接。每次推送数据时会根据map中的key取出所有的连接然后遍历发送消息。当关闭一个WebSocket连接根据key取出list使用List接口的remove方法移除该连接。服务端提示ConcurrentModificationException导致业务执行异常。问题分析ConcurrentModificationException 是 Java 中的一个运行时异常当在一个迭代过程中对集合如 ArrayList, LinkedList, HashSet, HashMap 等进行了修改如添加或删除元素而这种修改不是通过迭代器自身的方法如 Iterator.remove() 或 ListIterator.add()完成的就会抛出 ConcurrentModificationException。例如list.remove()。这种异常表明集合正在进行结构上的修改而迭代器没有预期到这种变化。以下是一个简单的示例展示如何触发 ConcurrentModificationExceptionimportjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;publicclassConcurrentModificationExample{publicstaticvoidmain(String[]args){ListStringlistnewArrayList();list.add(one);list.add(two);list.add(three);IteratorStringiteratorlist.iterator();while(iterator.hasNext()){Stringitemiterator.next();if(two.equals(item)){// 修改集合同时迭代list.remove(item);// 这里会抛出 ConcurrentModificationException}}}}本片文章中的问题也在于此当通过遍历ListPerformWebSocket对每个连接发送消息。同时用户关闭websocket连接在另一个线程中尝试通过集合的remove方法删除元素。于是产生这个错误。解决方案要避免 ConcurrentModificationException可以采用以下几种方法之一使用迭代器的 remove 方法如果需要删除元素确保使用迭代器的 remove() 方法而不是直接调用集合的 remove() 方法。IteratorStringiteratorlist.iterator();while(iterator.hasNext()){Stringitemiterator.next();if(two.equals(item)){iterator.remove();// 正确的做法}}使用 Collections.synchronizedList使用同步列表可以防止并发修改异常但这会降低性能因为每次修改都需要同步。ListStringsynchronizedListCollections.synchronizedList(newArrayList());使用 CopyOnWriteArrayList如果应用程序需要频繁地读取集合并且偶尔修改集合可以考虑使用 CopyOnWriteArrayList 或 CopyOnWriteArraySet这些集合类会在修改时创建一个新的副本。ListStringlistnewCopyOnWriteArrayList();创建不可变视图如果只是需要遍历集合而不打算修改它可以使用 Collections.unmodifiableList 创建一个不可变视图。ListStringunmodifiableListCollections.unmodifiableList(list);使用并发集合如果应用程序需要高度并发的访问可以使用 ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentLinkedQueue 等并发集合。总结ConcurrentModificationException 是并发编程中常见的问题通常是因为集合被多个线程共享并且在迭代过程中被意外修改。通过上述解决方案可以有效地避免这类问题的发生。愿你我都能在各自的领域里不断成长勇敢追求梦想同时也保持对世界的好奇与善意。