如何迭代并修改这个Arraylist?

时间:2016-03-17 13:06:46

标签: java multithreading

我有一个我在两个线程之间共享的arrayList,我正在尝试迭代并同时修改列表。我不想使用迭代器的方法,我也使用了同步列表,但它仍然提供concurrentmodificationexception

代码如下:

public class testing {
  public static void main(String args[]){

  ArrayList<String> al = new ArrayList<String>();
  List<String> sal=Collections.synchronizedList(al);
   String names[] = {"amol","Robin","vikas","shanu","mahesh"};
  for(String x :names){
       al.add(x);
  }      

  Thread t1 = new Thread(new SyncArrayList(sal));
  Thread t2 = new Thread(new SyncArrayList(sal));    
  t1.setName("T1");
  t2.setName("T2");
  t1.start();
  t2.start();

  }   
}

class SyncArrayList implements Runnable
{
 List<String> unsync ;

SyncArrayList(List<String> l){
   this.unsync = l;
}

@Override
public void run() {
    displayUnsyncList();
    addNames();
  }

void displayUnsyncList(){
   synchronized(this){ 
   ListIterator<String> itr = unsync.listIterator();
  while(itr.hasNext()){
      String x = itr.next();
      System.out.println("Thread " +Thread.currentThread().getName() + " is displaying name : "+x);
   } 
  }
 }

void addNames(){
    unsync.add("preet");
   } 

}   

3 个答案:

答案 0 :(得分:2)

在多线程环境中,您应该考虑使用CopyOnWriteArrayList来生成ConcurrentModificationException

答案 1 :(得分:1)

Collections.synchronizedList(...)的{​​{3}}解释了您需要做的事情:

   void displayUnsyncList() {
       synchronized (unsync) {
       ListIterator<String> itr = unsync.listIterator();
       while (itr.hasNext()) {
           String x = itr.next();
           System.out.println("Thread " + 
                              Thread.currentThread().getName() + 
                              " is displaying name : " + x);
       } 
   }

简而言之,您的代码正在同步错误的对象。

答案 2 :(得分:0)

您正在使用的迭代器是fail-fast iterator.Fail-fast迭代器直接读取内部数据结构。迭代整个集合时不应修改内部数据结构。

当一个或多个线程在集合上进行迭代时,您应该使用故障安全迭代器,在这两个线程之间,一个线程会更改集合的结构。

public static void main(String args[]) {

    ArrayList<String> al = new ArrayList<String>();
    List<String> sal = Collections.synchronizedList(al);
    String names[] = { "amol", "Robin", "vikas", "shanu", "mahesh" };
    for (String x : names) {
        al.add(x);
    }

    Thread t1 = new Thread(new SyncArrayList(sal));
    Thread t2 = new Thread(new SyncArrayList(sal));
    t1.setName("T1");
    t2.setName("T2");
    t1.start();
    t2.start();

}

}

类SyncArrayList实现Runnable {     列出unsyn;

// List<String> unsync = Collections.synchronizedList(unsyn);

SyncArrayList(List<String> l) {
    this.unsyn = new CopyOnWriteArrayList<String>(l);
}

@Override
public void run() {
    displayUnsyncList();
    addNames();
}

void displayUnsyncList() {
    synchronized (this) {
        Iterator<String> it = unsyn.iterator();
        while (it.hasNext()) {
            System.out.println("Thread " + Thread.currentThread().getName() + " is displaying name : " + it.next());
        }
    }
}

void addNames() {
    unsyn.add("preet");
}