java.util.ConcurrentModificationException问题原因

今天收到一个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可以看到 各种类型的可能发生此问题的数据结构。

发布了17 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/caizehui/article/details/103886406