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可以看到 各種類型的可能發生此問題的數據結構。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章