异常的相关文档在网上比比皆是,这里不具体描述java类的内部处理方式,仅仅就访问页面标签时发生该异常讨论起。只阐述可能会引起该异常的地方而不具体阐明为什么会出现。
项目相关环境:linux、jdk5.0、oracle10g、spring2.0+hibernate3.2+webwork2.2.5
最近在服务器上运行项目访问jsp页面过程中总会抛出以下异常信息
但是在本地进行测试过程中却无法还原该异常。最后经过一番周折后问题最终得到解决。
首先定位问题所在,发现异常的抛出点是在webwork解析ww:doubleselect 标签时产生。该处标签源码如下
这里我们使用了页面调用静态方法来实现需要迭代的省市联动菜单数据。具体的类代码如下
但在查看了该类的具体方法外,发现该类方法除了可以优化外,并没有能产生异常的地方。
开始怀疑是否是在调用 Collection的clear()方法是出现了该异常!但在测试过程中发现并未发现调用clear()方法会产生java.util.ConcurrentModificationException异常,同时结合API也并未发现API中有提到调用Collection 的clear()方法是会抛出该异常。
实在无奈下只好去看API中关于java.util.ConcurrentModificationException的解释,发现有如下解释
当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
例如,某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不明确的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常。执行该操作的迭代器称为快速失败 迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任意发生不确定行为的风险。
注意,此异常不会始终指出对象已经由不同 线程并发修改。如果单线程发出违反对象协定的方法调用序列,则该对象可能抛出此异常。例如,如果线程使用快速失败迭代器在 collection 上迭代时直接修改该 collection,则迭代器将抛出此异常。
注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。因此,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法,正确做法是:ConcurrentModificationException 应该仅用于检测 bug
那么该异常既然是由于是在多线程下才会发生那么首先根据API的提示写个测试类先还原该问题,写测试类如下
果不其然,在这种情况下打印出“error
”。将每个线程在取一个值时的休息时间改大时,程序抛出error的个数也个增加。那么现在就可以解释,为什么同一段程序在测试过程不会发生该异常,是由于页面的并发访问量没有达到让不同线程对省市联动集合进行迭代和clear()冲突的程度。
就像API中对于java.util.ConcurrentModificationException的解释,在对Collection迭代的过程中,是不允许其他线程对该共享Collection进行值修改的,如果修改就会抛出java.util.ConcurrentModificationException;同时经过测试发现,该异常通常不会出现在对Collection进行clear()、remove()时,而是出现在对Collection进行迭代的过程中.
更改静态类方法即可避免该问题
分享到:
相关推荐
Java.util.ConcurrentModificationException 异常问题详解 ConcurrentModificationException 异常是 Java 中一个常见的异常,它发生在 Iterator 遍历集合时,集合同时被修改引起的异常。在 Java 中,集合类如 ...
java.util.ConcurrentModificationException 解决方法 在使用iterator.hasNext()操作迭代器的时候,如果此时迭代的对象发生改变,比如插入了新数据,或者有数据被删除。 则使用会报以下异常: Java.util....
在Java编程中,`java.util.ConcurrentModificationException` 是一个常见的运行时异常,通常发生在尝试并发修改集合时。这个异常的产生是由于集合类(如HashMap)的非线程安全特性,当你在一个线程中使用迭代器遍历...
在Java编程中,`ConcurrentModificationException`是一个常见的运行时异常,主要出现在多线程环境下对集合类(如List、Set、Map等)进行并发修改时。然而,这个异常不仅限于多线程环境,即使在单线程中,如果在遍历...
但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除元素),Iterator将抛出ConcurrentModificationException异常。 Set接口是Collection接口的子接口...
这是Java中最常见的错误之一,当尝试访问一个为null的对象的成员时,程序会抛出此异常。避免这种问题的方法是始终确保对象在使用前已经被初始化,或者在访问其成员之前进行非null检查。 二、数组越界异常...
这意味着在多线程环境下,当一个线程正在遍历集合(通过迭代器进行)时,另一个线程修改了集合内容,就会触发快速失败(fail-fast)机制,导致ConcurrentModificationException异常。例如,上述代码中,线程在删除...
- `Enhanced for loop`在遍历过程中不允许直接修改正在迭代的集合,否则会抛出`ConcurrentModificationException`异常。 - 当需要在遍历的同时修改集合时,应考虑使用`Iterator`或其他方法。 #### 四、进阶篇:...
java.util.ConcurrentModificationException: mutation occurred during iteration [error] scala.collection.mutable.MutationTracker$.checkMutations(MutationTracker.scala:43) [error] scala.collection....
- `CopyOnWriteArrayList`和`CopyOnWriteArraySet`:这些列表和集在线程安全的迭代器上有优势,因为它们在修改时复制底层数组,从而避免了迭代过程中的并发修改异常(`ConcurrentModificationException`)。...
- `java.util.Iterator`的改进:支持`remove()`操作,避免抛出`ConcurrentModificationException`。 ### 4. 性能优化 JDK 1.6对编译器和垃圾收集器进行了优化,提高了运行效率,例如: - **Server VM的改进**: ...
在Java编程语言中,集合框架(`java.util`包)提供了多种容器类来存储对象,如`List`、`Set`和`Map`等。为了遍历这些容器中的元素,Java引入了迭代器模式(Iterator Pattern),这是一种常用的设计模式,它提供了一...
在Java编程中,`ConcurrentModificationException`是一个常见的运行时异常,通常发生在多线程环境下对集合进行迭代和修改操作时。此问题的核心在于,Java的集合类(如ArrayList、LinkedList、HashSet等)并不支持...
11. **NullPointerException**和**NullPointerException**:这两种异常在多线程编程中尤为常见,由于并发访问共享资源可能导致数据不一致,因此应使用`synchronized`关键字或`java.util.concurrent`包中的工具来管理...
《Java 7编程高级进阶》是一本专为有经验的Java开发者设计的教程,旨在深化对Java 7特性和高级编程技术的理解。...《Java 7编程高级进阶》这本书将引导你深入理解这些概念,帮助你在实际项目中充分利用Java 7的优势。
- `ConcurrentModificationException`: 如果在迭代过程中,集合结构被其他线程修改,可能会抛出此异常。为了避免这种问题,通常建议在迭代时不要直接修改集合,或者使用`ListIterator`的`add()`方法添加元素。 6. ...
3. **线程池**:`java.util.concurrent.ExecutorService`和`ThreadPoolExecutor`是Java中实现线程池的主要类。通过线程池可以有效地管理线程的创建和销毁,提高系统资源利用率,避免大量线程创建和销毁带来的开销。 ...
在多线程环境中,只读集合特别有用,因为它们能防止并发修改异常(`ConcurrentModificationException`)。当多个线程试图同时修改集合时,可能会出现这种问题。只读集合确保了即使在并发环境下,数据也能保持一致。 ...