java 并发修改_并发修改异常(ConcurrentModificationException)

并发修改异常(ConcurrentModificationException)

这个异常,使用集合的时候应该很常见,这个异常产生的原因是因为java中不允许直接修改集合的结构。

先贴上个有趣的例子,给你们看看:

package com.xiongda;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

public class Confirm {

public static void main(String[] args) {

List list = new ArrayList<>();

list.add("1");

list.add("2");

list.add("4");

list.add("3");

list.add("6");

Iterator iterator = list.iterator();

while(iterator.hasNext()){

String integer = iterator.next();

if(integer.equals("2")) {

list.remove("2");

}

}

System.out.println(list.toString());

}

}

我们使用list的remove方法删除元素,就抛出了这种并发修改异常,如下:

23504e52e7f735dcf334da54678dd47e.png

但是,我们改为判断倒数第二个数,删除任意元素,就不报错了:

package com.xiongda;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

public class Confirm {

public static void main(String[] args) {

List list = new ArrayList<>();

list.add("1");

list.add("2");

list.add("4");

list.add("3");

list.add("6");

Iterator iterator = list.iterator();

while(iterator.hasNext()){

String integer = iterator.next();

if(integer.equals("3")) {

list.remove("2");

}

}

System.out.println(list.toString());

}

}

c9b0e8c0d18e28a5e24373898802b196.png

这是为什么?是不是很神奇?

我昨天研究过源码之后发现,为什么使用arraylist的remove方法会抛出这个异常呢,因为arraylist中的add和remove方法都造成了modcount 和 exceptmodcpiunt不等。

而异常中抛出异常的那个方法checkformodification方法就是检查这两个值知否相等。

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

那么为什么,但判断走到了倒数第二个元素,删除就没有抛出异常了呢?

仔细看抛出的异常,是next方法里面调用的checkformodification方法:

public E next() {

checkForComodification();

int i = cursor;

if (i >= size)

throw new NoSuchElementException();

Object[] elementData = ArrayList.this.elementData;

if (i >= elementData.length)

throw new ConcurrentModificationException();

cursor = i + 1;

return (E) elementData[lastRet = i];

}

当判断到倒数第二个的时候,remove掉了一个,此时的index和size相等了,就不执行循环了,就不执行next方法了,所以异常就没有抛出来了

public boolean hasNext() {

return cursor != size;

}

那么为什么使用迭代器的remove方法不会报错,而使用arraylist的remove方法会报错呢?

这是因为list中的remove方法会使modcount++,但是迭代器中remove方法中多了一条modcount = exceptmodcount语句使其相等,所以使用迭代器不会报错

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值