今天在对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);
}
问题解决。
分享到:
相关推荐
下面详细解析一下这个问题的原因和解决策略: 1. **原因分析**: - 当你使用`for-each`循环(增强for循环)遍历集合时,实际上底层是通过迭代器实现的。但是,如果你在循环内部直接修改集合(比如删除元素),而...
在Java编程中,`java.util.ConcurrentModificationException` 是一个常见的运行时异常,通常发生在尝试并发修改集合时。这个异常的产生是由于集合类(如HashMap)的非线程安全特性,当你在一个线程中使用迭代器遍历...
`java.util.ConcurrentModificationException` 是一个在 Java 中常见的运行时异常,它通常发生在多线程环境中,当一个线程正在遍历一个集合(如 `ArrayList`, `HashMap` 等),而另一个线程同时尝试修改这个集合时。...
### Java常见问题及解决方案 #### 一、编译错误 **1.1 问题:** "cannot find symbol" **解决:** 这个错误提示通常意味着Java编译器未能找到指定的类、方法或变量。要解决这个问题,需要进行以下几个步骤的检查: ...
原因在于,在增强for循环中,实际上是使用Iterator来遍历List,而Iterator并不能检测到List的变化,从而导致异常。 解决方法 要解决List遍历删除元素的问题,可以使用Iterator来遍历List,并使用Iterator的remove...
需要注意的是,代码示例在本问题描述中由于OCR扫描的原因无法提供,所以在具体实现这些解决方案时,开发者应该参考Java官方文档或相应的编程指南来确保正确和有效的代码实现。 通过这些方法,可以有效解决在使用`...
例如,可能是在遍历`Map`时没有正确地处理`Iterator`,导致并发修改异常(`ConcurrentModificationException`);或者是在查找或插入键值对时遇到了键的唯一性问题;也可能是性能问题,比如在大量数据上使用了不适合...
### Java常见错误集合以及...通过了解这些异常的原因及解决方案,可以帮助开发者更好地处理异常情况,提高程序的健壮性和稳定性。此外,合理的异常处理策略也是提高开发效率的关键。希望本文能对Java开发者有所帮助。
10. **ConcurrentModificationException**:在多线程环境下,当一个线程正在修改集合,而另一个线程尝试遍历同一集合时,会抛出此异常。使用并发控制或使用不可变集合来避免。 以上仅是Java环境报错中的一部分,...
在实际开发中,理解这些异常及其原因可以帮助我们编写更健壮的代码。为了正确处理这些异常,我们可以使用try-catch块,或者使用Java 7引入的`try-with-resources`语句来确保资源的正确关闭。此外,良好的编程习惯和...
当你遇到“方法iterator()找不着的问题”时,这通常意味着你在尝试使用`iterator()`时遇到了错误,可能是由于以下几个原因: 1. **类库不兼容**: 如果你正在使用的类库版本不支持`iterator()`方法,比如你引用了...
以上仅列举了部分Android开发中常见的错误类型,理解它们的原因和解决方法是提升开发效率和应用质量的关键。在实践中,通过日志调试、使用Android Studio提供的分析工具,以及学习更多Android SDK文档,可以更好地...
- **面向过程:** 侧重于定义一系列的过程来解决问题,更注重算法的设计。 #### 七、面向对象的特性 - **封装:** 将数据和行为绑定在一起,隐藏对象的内部状态。 - **继承:** 允许子类继承父类的属性和方法。 - **...
- 在遍历集合时对其进行修改可能会导致`ConcurrentModificationException`异常。为了安全起见,在循环外部进行修改操作。 #### 四、异常处理 1. **合理捕获并处理异常** - 不应该忽视任何异常,而是应该适当地...
通过查看项目源代码,我们可以更具体地定位问题所在,比如查看日志文件、异常堆栈跟踪等,以找出引发"SurpriseError"的具体原因。 为了提高代码质量和防止未来出现类似的“惊喜”错误,开发者应该遵循良好的编程...
在使用迭代器遍历集合的过程中,如果通过集合对象修改了集合中的元素(如添加、删除等操作),会导致迭代器获取元素时判断预期修改值和实际修改值不一致,从而抛出`ConcurrentModificationException`异常。...
在多线程环境中,如果对正在遍历的集合进行修改,会立即抛出`ConcurrentModificationException`异常。 2. **安全失败**: - `java.util.concurrent`包下的类(如`CopyOnWriteArrayList`)采用安全失败机制。遍历时...
这样做的原因是`iterator.remove()`会更新迭代器的内部状态,使得`modCount`和`expectedModCount`保持一致,避免抛出异常。 3. **使用for循环正序遍历** 另一种方法是使用传统的for循环,通过索引来访问和删除...
- **操作风险**:在遍历集合时修改集合本身会导致`ConcurrentModificationException`异常。 - **应对策略**:若需要在遍历过程中删除或添加元素,推荐使用迭代器提供的`remove`方法,或者先复制集合再进行操作。 ##...
对于ArrayList而言,直接在foreach循环中进行元素的remove或add操作可能会导致`ConcurrentModificationException`,因为这违反了迭代器的协定。应使用`Iterator`进行这类操作。 7. **避免直接使用日志系统的API**...