集合操作的ConcurrentModificationException

1.产生情景

      在做项目中遇到如下需求:遍历集合,删除其中值=2的元素。代码如下:

	@Test
	public void test() 
	{
		List<Integer> list = new ArrayList<Integer>();
		list.add(0);
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		
		for (Integer integer : list) 
		{
			if (integer==2) 
			{
				list.remove(2);
			}
		}
	}
            运行后抛出如下异常:

java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
	at java.util.AbstractList$Itr.next(Unknown Source)
	at com.mycompany.app.ConcurrentModifyTest.test(ConcurrentModifyTest.java:22)

2.产生原因

      ArrayList等的Collection的实现并没有同步化(也就是没有synchronized),如果在多线程应用中出现同时访问和修改时,要求外部操作必须要同步,如果不是同步就会抛出这个异常。

     简单地说就是:不能在遍历的时候通过list、map等容器本身删除其中的元素


3.单线程的解决方案

      既然不能通过容器来删除,那么就使用迭代器本身的remove方法来删除即可

	@Test
	public void test() 
	{
		List<Integer> list = new ArrayList<Integer>();
		list.add(0);
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		
		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) 
		{
			Integer i = iterator.next();
			if (i==2) 
			{
				iterator.remove();
			}
		}
	}

4.多线程的解决方案

      单线程的解决方案在多线程情况下就不适用了,而且就算是将ArrayList换为同步容器Vector也还是会出现这种问题。

      解决方案有以下两种:

     (1)使用并发容器推荐

                如CopyOnWriteArrayList代替ArrayList和Vector,用ConcurrentHashMap代替HashMap

     (2)通过synchronized或者Lock将iterator操作放入其中


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值