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