ArrayList安全问题
public class ContainerNotSafeDemo {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
for (int i = 1; i < 31; i++) {
new Thread(() -> {
strings.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(strings);
}, String.valueOf(i)).start();
}
}
}
在多个线程同时向ArrayList
中加入数据时,会出现concurrentModificationException
异常。
解决方案
- voctor
- Collections.synchorizedArrayList<>(new ArrayList<>())
- new CopyOnWriteArrayList()
CopyOnWriteArrayList
内部属性
private transient volatile Object[] array;
final Object[] getArray() {
return array;
}
final void setArray(Object[] a) {
array = a;
}
add(E e)
/**
* 追加一个特殊元素在list集合的最后
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
//获得lock锁,上锁
lock.lock();
try {
//获取数组
Object[] elements = getArray();
//数组长度
int len = elements.length;
//创建一个新的长度+1的数组,并且把元素复制过去
Object[] newElements = Arrays.copyOf(elements, len + 1);
//尾部追加元素
newElements[len] = e;
//设置数组
setArray(newElements);
//通知去读新的数组
return true;
} finally {
//解锁
lock.unlock();
}
}