13.13 java.util.ConcurrentModificationException

简介: 13.13 java.util.ConcurrentModificationException问题描述在H5性能测试平台系统的开发过程中,客户端调用服务端API,写入性能数据的时候,报了如下错误:java.

13.13 java.util.ConcurrentModificationException

问题描述

在H5性能测试平台系统的开发过程中,客户端调用服务端API,写入性能数据的时候,报了如下错误:

java.util.ConcurrentModificationException at 
java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)

错误代码:

    /**
     * 记录性能数据,写入server的数据库中
     *
     * @param requestResources
     */

    private void recordPerfData(List<HashMap<String, String>> requestResources) {
        Log.i("TAGH5", "requestResources=" + JSON.toJSONString(requestResources));
        for (HashMap<String, String> map : requestResources) {
            Log.i("TAGH5", "map=" + JSON.toJSONString(map));
            callWriteRequestResourceHttpApi(map);
        }
    }

原因分析

foreach循环,在使用iterator.hasNext()操作迭代器的时候,如果此时迭代的对象发生改变,比如插入了新数据,或者有数据被删除。此时,调用迭代器取数据ArrayListIterator.next(),会报上面的异常。

所以,涉及集合类的多线程的场景的操作的时候,要小心。

解决办法

  1. 通过Iterator修改Hashtable
while(it.hasNext()) {
Object ele = it.next();
            it.remove();
}
  1. 手动给Iterator遍历代码加锁,给修改HashMap的代码加锁。
  1. 使用CopyOnWriteArrayList

CopyOnWriteArrayList是java.util.concurrent包中的一个List的实现类。

CopyOnWrite的意思是在写时拷贝,也就是如果需要对CopyOnWriteArrayList的内容进行改变,首先会拷贝一份新的List并且在新的List上进行修改,最后将原List的引用指向新的List。

使用CopyOnWriteArrayList可以线程安全地遍历,因为如果另外一个线程在遍历的时候修改List的话,实际上会拷贝出一个新的List上修改,而不影响当前正在被遍历的List。

上面的报错代码修改如下:

recordPerfData(CopyOnWriteArrayList<HashMap<String, String>> requestResources)
  1. 如果是HashMap使用“ConcurrentHashMap”替换HashMap,ConcurrentHashMap会自己检查修改操作,对其加锁,也可针对插入操作。
import java.util.concurrent.*;

小结

遍历List的同时操作List会发生异常:

java.util.ConcurrentModificationException

相关文章
|
7天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
35 17
|
3月前
|
安全 Java
Java 中的 CopyOnWriteArrayList
【8月更文挑战第23天】
26 0
|
6月前
|
消息中间件 安全 Java
【JavaEE】JUC(Java.util.concurrent)常见类
【JavaEE】JUC(Java.util.concurrent)常见类
|
6月前
|
安全 Java 容器
使用场景和方法介绍:java.util.concurrent.CopyOnWriteArrayList
使用场景和方法介绍:java.util.concurrent.CopyOnWriteArrayList
49 0
|
存储 缓存 安全
报错:java.util.ConcurrentModificationException 线程不安全
今天在做项目时,遇到个bug,需求是app在特定的时候把广告缓存下来,合适的位置在展示,于是想的用hashmap列表存起来,key为位置的广告类型,value为广告对象。为了保证每个位置同时缓存的对象只有一个,于是在存储(add方法)前会将列表遍历一遍,如果有就remove掉。但是请求广告有时候并不在一个线程,于是今天在运行时,App闪退了。
java.lang.UnsupportedOperationException
java.lang.UnsupportedOperationException
106 0
【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(上)
【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(上)
【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(上)
|
算法 搜索推荐 Java
【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(中)
【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(中)
|
Java
java源码-java.util.List
public List<String> findAddressesByApplication(String application) { List<String> ret = new ArrayList<String>(); ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().
1196 0