基于源码理解通透Iterator迭代器的Fail.docx
第
基于源码理解通透Iterator迭代器的Fail
privatevoidensureCapacityInternal(intminCapacity){
ensureExplicitCapacity(calculateCapacity(elementData,minCapacity));
privatevoidensureExplicitCapacity(intminCapacity){
modCount++;
//overflow-consciouscode
if(minCapacity-elementData.length0)
grow(minCapacity);
总结一下,迭代器创建时,变量expectedModCount是被modCount赋值,在整个迭代器等生命周期中,变量expectedModCount值是固定的了,但在第一轮遍历过程中,通过list.add(李华)操作,导致modCount++,最终就会出现expectedModCount!=modCount。因此,在迭代器进行第二轮遍历时,执行到Stringitem=(String)iterator.next(),在next()里调用checkForComodification()判断expectedModCount是否还等于modCount,这时已经不等于,故而就会抛出ConcurrentModificationException异常,立刻结束迭代器遍历,避免数据不一致。
finalvoidcheckForComodification(){
if(modCount!=expectedModCount)
thrownewConcurrentModificationException();
以上,就是集合迭代器的Fail-Fast机制原理。
二、迭代器的Fail-Safe(安全失败)机制原理
Fail-Fast(快速失败)机制案例,用集合CopyOnWriteArrayList来说明,这里用一个线程就能模拟出该机制
publicstaticvoidmain(String[]args){
CopyOnWriteArrayListStringlist=newCopyOnWriteArrayList();
list.add(张三
list.add(李四
list.add(王五
Iteratoriterator=list.iterator();
while(iterator.hasNext()){
Stringitem=(String)iterator.next();
list.add(李华
System.out.println(item);
System.out.println(最后全部打印集合结果:+list);
执行这段代码,正常打印结果,说明在迭代器遍历过程中,对集合做了新增元素操作,并不影响迭代器遍历,新增的元素不会出现在迭代器遍历当中,但是,在迭代器遍历完成后,再一次打印集合,可以看到新增的元素已经在集合里了
最后全部打印集合结果:[张三,李四,王五,李华,李华,李华]
Fail-Safe(安全失败)机制在CopyOnWriteArrayList体现,可以理解成,这是一种读写分离的机制。
下面就看一下CopyOnWriteArrayList是如何实现读写分离的。
先来看迭代器的创建Iteratoriterator=list.iterator(),进入到list.iterator()底层源码
publicIteratorEiterator(){
returnnewCOWIteratorE(getArray(),0);
这里的COWIterator是一个迭代器,关键有一个地方,在创建迭代器对象,调用其构造器时传入两个参数,分别是getArray()和0。
这里的getArray()方法,获取到一个array数组,它是CopyOnWriteArrayList集合真正存储数据的地方。
finalObject[]getArray(){
returnarray;
另一个参数0,表示迭代器遍历的索引值,刚开始,肯定是从数组下标0开始。
明白getArray()和0这两个参数后,看一下迭代器创建newCOWIterator(getArray(),0)的情况,只需关