`
lc_koven
  • 浏览: 350355 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ConcurrentModificationException异常的原因及解决

阅读更多
    今天在对map进行遍历的程序中发现抛出ConcurrentModificationException 异常:

    一个线程中:
Map<byte[],byte[]> map = new ConcurrentHashMap<byte[],byte[]>();
			while((row = results.next()) != null){
				map.clear();
				...
				queue.put(map);
			}


    另一个线程中:

while(queue.size() > 0){
				line = queue.poll();
				if(line == null)
					continue;
				Iterator<Map.Entry<byte[],byte[]>> it = line.entrySet().iterator();
				while(it.hasNext()){
					...
				}
			}

    即使读写线程分别只用一个,也会抛出该异常。

    原因是Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
(http://www.iteye.com/topic/124788)

    所以当读线程中执行了map.clear()后,写线程的Iterator指向的原始对象就变化了,导致抛出异常。修改读线程代码为:
Map<byte[],byte[]> map;
			while((row = results.next()) != null){
				map = new ConcurrentHashMap<byte[],byte[]>();
				...
				queue.put(map);
			}


    问题解决。
0
3
分享到:
评论
2 楼 lc_koven 2011-09-10  
nowopen 写道
ConcurrentHashMap应该不会有ConcurrentModificationException异常,是不是其他原因?

Set<Entry<K, V>> java.util.concurrent.ConcurrentHashMap.entrySet()Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

恩,大师,ConcurrentModificationException 是从List中抛出的,这里就是queue。当map执行clear后,再去访问原来put到queue中的元素后就出错了。我代码可能没有引用完
1 楼 nowopen 2011-09-09  
ConcurrentHashMap应该不会有ConcurrentModificationException异常,是不是其他原因?

Set<Entry<K, V>> java.util.concurrent.ConcurrentHashMap.entrySet()Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

相关推荐

Global site tag (gtag.js) - Google Analytics