小心修改集合的大小 (转)

本文探讨了Java中集合的快速失败机制导致的ConcurrentModificationException异常问题,并提供了两种解决方案:一是确保迭代过程中仅通过Iterator的remove方法来删除元素;二是对于多线程环境下,建议克隆集合而非直接修改。
小心修改集合的大小 (转)[@more@]

小心修改集合的大小XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

 

  Java中最常使用的就是集合了,而且处于性能的考虑,现在大部分人都不再使用Vector这种方法同步的集合了。新的集合库带来了更快的性能,同时也带来了更多错误使用的可能。新集合库性能的提升主要就是去掉了方法同步,可想而知,同步访问时必然存在数据一致性问题。为了能使程序不会因为数据的不一致而造成其它错误,新集合库在设计时采用了快速失败机制(Fast-Fail),就是每次遍历集合时都会判断当前集合大小是否被修改,如果被修改,马上抛出ConcurrentModificationException异常,停止程序继续运行。因此集合初始化完成后,应避免在另一处被修改大小。看下面这个例子:

package com.bhr.ioat.testcollection;

import java.util.*;

public class TestRemove

{

  public static void main(String[] args)

  {

    Collection cltn = new ArrayList();

  for(int i=0; i<100000; i++){

    cltn.add(new Integer(i));

  }

  new OtherThread(cltn).start();

  try{

    Thread.sleep(1000); //sleep 1 second, in order to ensure the new thread start up.

    }catch(Exception e){

    e.printStackTrace();

  }

    Iterator it = cltn.iterator();

    while(it.hasNext()){

    object obj = it.next();

    cltn.remove(obj);

    //it.remove();

    System.out.println("Remove one element from collection");

    break;

  }

 

  }

}

 

class OtherThread extends Thread

{

  public Collection cltn_;

  public OtherThread(Collection cltn){

  cltn_ = cltn;

  //cltn_ = (Collection)(((ArrayList)cltn).clone());

  }

 

  public void run(){

    Iterator it = cltn_.iterator();

    while(it.hasNext()){

    Object obj = it.next();

    System.out.println(obj);

  }

  }

 

}

程序很简单,开始初始化一个100000大小的ArrayList,然后传给另一个类,随后删除集合中的一个元素,你会发现马上就会抛出ConcurrentModificationException异常。

那是不是就不可以删除元素了?是不是应该继续使用Vector?当然不是,要不新集合的出现岂不是失去了意义。解决方法有两个,(1)集合只在一处被使用,这自然没有并发问题,不过还是不可以大胆修改,如果循环中删除集合中的元素,一定要调用Iterator的remove方法,而不是Collection的remove方法,前者删除后会修改Iterator的一个值,使得循环以为集合没被修改,可以继续进行,而调用后者没有修改Iterator中的值,继续循环同样会抛出异常。至于添加元素,Iterator中没有提供相应方法,所以如果在循环中添加,添加后就只能跳出循环了。(2)同一个集合在多处被使用,索性不要删除了,本来这种情况就不应该修改集合大小,如果你决得集合大小的修改不会影响程序的正常逻辑,那么使用时只好clone一个了。

上面只是实际中总结得一点经验,如果大家有更好得方法,可以交流一下,E-Mail:zhvfeng@hotmail.com

 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-998001/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-998001/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值