- 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一个了。