今天收到一个bug,查了好久,才找到java.util.ConcurrentModificationException这个异常。
归根结底就是多线程问题, 多线程使用时不允许修改,解决方案就是对象加锁。
报错的地方显示
01-07 11:13:15.590 3526 3539 E JavaBinder: at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
01-07 11:13:15.590 3526 3539 E JavaBinder: at java.util.HashMap$KeyIterator.next(HashMap.java:833)
在hashmap源码中可以看到,如果两个值不等则会抛出异常。
java.utils.HashMap.java
/** * The number of times this HashMap has been structurally modified * Structural modifications are those that change the number of mappings in * the HashMap or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). */ transient int modCount;
if (modCount != mc) throw new ConcurrentModificationException();
if (modCount != expectedModCount) throw new ConcurrentModificationException();
而异常类的定义如下
/** * This exception may be thrown by methods that have detected concurrent * modification of an object when such modification is not permissible. 第一句注释就说明了,如果一个对象被检测到发生了并发操作就会抛出异常,因为并发时不允许修改。 * <p> * For example, it is not generally permissible for one thread to modify a Collection * while another thread is iterating over it. In general, the results of the * iteration are undefined under these circumstances. Some Iterator * implementations (including those of all the general purpose collection implementations * provided by the JRE) may choose to throw this exception if this behavior is * detected. Iterators that do this are known as <i>fail-fast</i> iterators, * as they fail quickly and cleanly, rather that risking arbitrary, * non-deterministic behavior at an undetermined time in the future. * <p> * Note that this exception does not always indicate that an object has * been concurrently modified by a <i>different</i> thread. If a single * thread issues a sequence of method invocations that violates the * contract of an object, the object may throw this exception. For * example, if a thread modifies a collection directly while it is * iterating over the collection with a fail-fast iterator, the iterator * will throw this exception. * * <p>Note that fail-fast behavior cannot be guaranteed as it is, generally * speaking, impossible to make any hard guarantees in the presence of * unsynchronized concurrent modification. Fail-fast operations * throw {@code ConcurrentModificationException} on a best-effort basis. * Therefore, it would be wrong to write a program that depended on this * exception for its correctness: <i>{@code ConcurrentModificationException} * should be used only to detect bugs.</i> * * @author Josh Bloch * @see Collection * @see Iterator * @see Spliterator * @see ListIterator * @see Vector * @see LinkedList * @see HashSet * @see Hashtable * @see TreeMap * @see AbstractList * @since 1.2 */ public class ConcurrentModificationException extends RuntimeException {
通过上述类的注释中@see可以看到 各种类型的可能发生此问题的数据结构。