其实主要是想讲下这个字段的作用
/**
* 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;
上面的代码是在ArrayList、HashMap、LinkedList中找到的,属性名一样,定义方式类似。
transient这个关键字主要就是让对象序列化时忽略modCount
我们来看看属性的说明
在结构上修改这个HashMap的次数,结构修改是指改变映射的数量HashMap或以其他方式修改其内部结构(例如重复)。此字段用于在集合视图上生成迭代器HashMap失败得很快。(见ConcurrentModificationException)。
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.
翻一下就是:
不允许同时检测到对象的同时修改的方法可能抛出此异常。例如,通常不允许一个线程修改Collection ,而另一个线程对其进行迭代。通常,在这些情况下迭代的结果是不确定的。如果检测到此行为,则某些Iterator 实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。这样做的迭代器称为 fail-fast 迭代器,因为它们快速干净地失败,而不是冒着在不确定的将来冒任意,不确定行为的风险。请注意,此异常并不总是表示对象已被不同线程同时修改。如果单个线程发出违反对象合同的方法调用序列,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
其实就是想告诉我们两件事
1:在遍历集合的时候去修改里面的元素会报异常
2:多线程操作不安全,也会引发异常
我们直接来看看代码吧
//来自HashMap源码
public final void forEach(Consumer<? super K> action) {
Node<K,V>[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
// Android-changed: Detect changes to modCount early.
for (int i = 0; (i < tab.length && modCount == mc); ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next)
action.accept(e.key);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
ArrayList、LinkedList 代码也类似,可以看出 他们都是线程不安全的,会抛ConcurrentModificationException异常
网友评论