ArrayList的ConcurrentModificationException异常和多线程下的异常
2024-10-19 00:20:54
一、ConcurrentModificationException
ArrayList源码看为什么出现异常:
public class ArrayList<e> extends AbstractList<e>
implements Cloneable, Serializable, RandomAccess { @Override public boolean remove(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++; // 只要删除成功都是累加
return true;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++; // 只要删除成功都是累加
return true;
}
}
}
return false;
} @Override public Iterator<e> iterator() {
return new ArrayListIterator();
} private class ArrayListIterator implements Iterator<e> {
...... // 全局修改总数保存到当前类中
/** The expected modCount value */
private int expectedModCount = modCount; @SuppressWarnings("unchecked") public E next() {
ArrayList<e> ourList = ArrayList.this;
int rem = remaining;
// 如果创建时的值不相同,抛出异常,
if (ourList.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (rem == 0) {
throw new NoSuchElementException();
}
remaining = rem - 1;
return (E) ourList.array[removalIndex = ourList.size - rem];
} ......
}
}
由上可知,如果遍历中作get,remove操作都会改变modCount的值,但是此时expectedModCount还是保存以前的modCount的值,肯定不相等,抛出异常。
二、多线程下的异常
1、发生 ArrayIndexOutOfBoundsException 异常;
问题是出现在多线程并发访问下,由于没有同步锁的保护,造成了 ArrayList 扩容不一致的问题。
2、程序正常运行,输出了少于实际容量的大小;
这个也是多线程并发赋值时,对同一个数组索引位置进行了赋值,所以出现少于预期大小的情况。
3、程序正常运行,输出了预期容量的大小;
这是正常运行结果,未发生多线程安全问题,但这是不确定性的,不是每次都会达到正常预期的。
三、线程安全的CopyOnWriteArrayList
Java并发集合(一)-CopyOnWriteArrayList分析与使用
最新文章
- WPF触发器的使用
- dom事件不求甚解,色解事件捕获和冒泡
- XML学习笔记(四)-- 修饰XML文档的CSS
- 【转】为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?
- 在mac系统上安装Eclipse,编写java程序
- PHP获取和操作配置文件php.ini的几个函数
- Mysql的联合查询
- kill -9杀掉nginx主进程、reload失败解决办法
- CodeForces 588A
- qt下的跨目录多工程编译
- ONLY三行脚本 SQL数据恢复到指定时间点
- ionic的安装
- (转)Spark性能优化:资源调优篇
- 向JSP中静态导入HTML文件时,运行jsp时,html中中文产生乱码问题最简单的解决方法
- [mongoDB]PyMongo Cursor Not Found Error
- 用python写MapReduce函数——以WordCount为例
- 如何创建一个 mongo 数据库并为它添加一个认证用户?
- 像黑客一样使用Linux命令行(转载)
- jQuery对象合并、jQuery添加静态方法、jQuery添加DOM实例方法
- C#右下角弹出消息框