ArrayList迭代器 fail-fast机制

Arsuf 2015-08-07 10:09:49
当一个线程迭代访问ArrayList,另一个修改ArrayList,则第一个迭代的线程会抛出ConcurrentModificationException异常。这就是fail-fast机制。

JDK文档这样说的:迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。

我想问的是:快速失败迭代器会尽最大努力抛出 ConcurrentModificationException怎么理解?
...全文
362 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
0萌萌哒0 2015-08-31
  • 打赏
  • 举报
回复
快速失败的意思分两个: 第一个是它会检查迭代过程中对原list的修改,在检测到修改后就抛出正在被迭代数组被异常修改的异常;这个异常与是否处于同一线程没有关系。 第二个是它的检测不能完全检查所有的修改(因为它是快速检查,完全的检查很费时间)。能检测到何种修改取决于该集合的迭代器的具体实现。(这种不保证检测到其实就是尽最大努力) 可以参考以下代码:

public static void main(String[] args) throws Exception{
	ArrayList<Integer> x = new ArrayList<>(Arrays.asList(1,2,3,4,5));
	Iterator<Integer> it = x.iterator();
	while(it.hasNext()) {
		System.out.println(it.next());
		// 此处修改不会被发现,不报异常
		x.set(0, 9);
	}
	System.out.println("-===第二次迭代====-");
	it = x.iterator();
	while(it.hasNext()) {
		System.out.println(it.next());
		// 此处修改会被发现,将在下次调用next()时报异常
		x.add(1);
	}
}
铁匠梁老师 2015-08-31
  • 打赏
  • 举报
回复
遍历个过程中,同时修改list内容,会引起遍历内容错乱。
解开者 2015-08-31
  • 打赏
  • 举报
回复
非并发的集合的Iterator是发起一个独立线程进行迭代操作,快速失败指的是如果对集合本身进行了异步修改(在其他线程中进行的),Iterator会尽可能感知到这一变化并抛出异常(因为异步修改可能影响迭代的正确性)。但这个操作本身也是异步的,因此只能做到尽可能正确而不是绝对正确
Arsuf 2015-08-30
  • 打赏
  • 举报
回复
快速失败是啥意思,哪里体现了“快速”?
落落叶叶无声 2015-08-07
  • 打赏
  • 举报
回复
迭代时每次一调用next()函数都会检查list是否被修改过来决定是否抛出ConcurrentModificationException,但是检查了之后未必就会正确的返回下一个元素,因为在返回的这一过程中list可能又被修改了或者越界了之类,所以会用trycatch块来检验,在catch块中判断是否抛出ConcurrentModificationException或者IndexOutOfBoundsException异常。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧