Java 集合中常见 checkForComodification()方法的作用? modCount和expectedModCount作用?

主要是用来实现fail-fast机制

有两个线程(线程A,线程B),其中线程A负责遍历list、线程B修改list。
-线程A在遍历list过程的某个时候(此时expectedModCount = modCount=N),线程启动,
同时线程B增加一个元素,这是modCount的值发生改变(modCount + 1 = N + 1)。 线程A继续遍历执行next方法时,
通告checkForComodification方法发现expectedModCount = N , 而modCount = N + 1,两者不等,
这时就抛出ConcurrentModificationException 异常,从而产生fail-fast机制。

/**
 * 当前取的是 JDK1.8 ArrayList中的代码
 */

/**
 * The number of times this list has been structurally modified.
 * Structural modifications are those that change the size of the
 * list, or otherwise perturb it in such a fashion that iterations in
 * progress may yield incorrect results.
 *
 * 

This field is used by the iterator and list iterator implementation * returned by the {@code iterator} and {@code listIterator} methods. * If the value of this field changes unexpectedly, the iterator (or list * iterator) will throw a {@code ConcurrentModificationException} in * response to the {@code next}, {@code remove}, {@code previous}, * {@code set} or {@code add} operations. This provides * fail-fast behavior, rather than non-deterministic behavior in * the face of concurrent modification during iteration. * *

Use of this field by subclasses is optional. If a subclass * wishes to provide fail-fast iterators (and list iterators), then it * merely has to increment this field in its {@code add(int, E)} and * {@code remove(int)} methods (and any other methods that it overrides * that result in structural modifications to the list). A single call to * {@code add(int, E)} or {@code remove(int)} must add no more than * one to this field, or the iterators (and list iterators) will throw * bogus {@code ConcurrentModificationExceptions}. If an implementation * does not wish to provide fail-fast iterators, this field may be * ignored. */ protected transient int modCount = 0;

在父类AbstractList中定义了一个int型的属性:modCount

protected transient int modCount = 0;

在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。
AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回:

public Iterator iterator() { return new Itr(); }

Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。

int expectedModCount = modCount;

注:内部成员类Itr也是ArrayList类的一个成员,它可以访问所有的AbstractList的属性和方法。理解了这一点,Itr类的实现就容易理解了。

在Itr.hasNext()方法中:

public boolean hasNext() { return cursor != size; }

调用了AbstractList的size,比较当前光标位置是否越界。

public Object next()  
{  
 try  
 {  
  Object next = get(cursor);  
  checkForComodification();  
  lastRet = cursor++;  
  return next;  
 }  
 catch(IndexOutOfBoundsException e)  
 {  
  checkForComodification();  
  throw new NoSuchElementException();  
 }  
}  
/**
* 在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操作
* 这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。
* 在AbstractList中,使用了一个简单的机制来规避这些风险。 
* 这就是modCount和expectedModCount的作用所在
*/
final void checkForComodification() {
   if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

你可能感兴趣的:(java)