使用List的迭代器时一定有所体会,当运行类似如下程序时,会抛出一个ConcurrentModificationException
Iterator iterator = list.iterator();
while(iterator.hasNext())
{
iterator.next()
list.add("haha");
set.remove();
}
---->iterator被创建后集合再发生改变就抛出 ConcurrentModificationException
关于这点,JDK又是怎样实现的呢?思想就是将iterator看成一个“临界区”,只是不是多线程而是单个线程内部的“临界”。这里借助于一个modCount,定义如下:
protected transient int modCount = 0;
在迭代过程中不允许修改原始list的方法中(如add,remove)每次对modCount自增1,比如add方法中通过ensureCapacity方法让modCount++,而在调用迭代器时(实际
上是初始化迭代器时)将modCount赋值给expectedModCount
int expectedModCount = modCount;
每次调用迭代器的next()方法就会进行checkForComodification()检查是否expectedModCount已经不等于 modCount,如果不等,说明在迭代过程中已经通过remove()或add()等方法对原集合进行过修改,这是不允许的,所以 checkForComodification()抛出ConcurrentModificationException异常;如果相等,说明迭代过程中集合没有被修改过。
为什么需要保证迭代中集合不能被修改呢?因为这样就不能保证集合能够被完全遍历到,因此,java的开发人员使用了这个比较巧妙的方法来解决这个问题。
Vector中,非常类似ArrayList,但是其中加入了同步锁,不同步的时候使用它是会降低效率的。
|
|