1.故障现象
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2982)
2.导致原因
多线程并发争抢同一个资源,比如,一个线程正在存数据,还没存bai好,另外du一个线程就进来取数据了,这就会导致数据错误!
3.解决办法
new Vector(),可以用Vector来解决线程安全问题。但是Vector是重锁,性能堪忧。
Collections.synchronizedList(new ArrayList<>()),synchronizedList实现线程安全的方法就是对自己(get、set、add、remove)暴力加锁,性能也不高
使用写时复制集合CopyOnWriteArrayList
new CopyOnWriteArrayList<>()
源码
public boolean add(E var1) {
ReentrantLock var2 = this.lock;
var2.lock();
boolean var6;
try {
Object[] var3 = this.getArray();
int var4 = var3.length;
Object[] var5 = Arrays.copyOf(var3, var4 + 1);
var5[var4] = var1;
this.setArray(var5);
var6 = true;
} finally {
var2.unlock();
}
return var6;
}
原理:读写分离思想
- 添加元素时使用lock锁防止并发问题
- 对原数组object[]复制,往新数组中添加元素
- 将原容器的应用指向新容器
补充:
HashSet底层是一个value值为常量的HashMap,也是线程不安全的集合,可用CopyOnWriteArraySet代替,原理同CopyOnWriteArrayList
private transient HashMap<E, Object> map;
public boolean add(E var1) {
return this.map.put(var1, PRESENT) == null;
}
jdk1.8的ConcurrentHashMap数组+链表+红黑树+cas乐观锁+synchronized锁