简体   繁体   English

如何迭代并修改这个Arraylist?

[英]How can iterate over and modify this Arraylist?

I have an arrayList which I am sharing between two threads and I am trying to iterate over and modify the list at the same time. 我有一个arrayList,我在两个线程之间共享,我试图迭代并同时修改列表。 I don't want to use the iterator's method, and I have also used the synchronized list but it still gives concurrentmodificationexception . 我不想使用迭代器的方法,我也使用了同步列表,但它仍然提供concurrentmodificationexception

code is as follows : 代码如下:

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");
   } 

}   

在多线程环境中,您应该考虑使用不会产生ConcurrentModificationException CopyOnWriteArrayList

The javadoc for Collections.synchronizedList(...) explains what you need to do: Collections.synchronizedList(...)javadoc解释了您需要执行的操作:

   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);
       } 
   }

In short, your code was synchronizing on the wrong object. 简而言之,您的代码正在同步错误的对象。

The iterator you are using is fail-fast iterator.Fail-fast iterator read internal data structure directly . 您正在使用的迭代器是fail-fast iterator.Fail-fast迭代器直接读取内部数据结构。 The internal data structure should not be modified while iterating through the collection. 迭代集合时不应修改内部数据结构。

You should use Fail-safe iterator when one or more thread is iterating over the collection, in between, one thread changes the structure of the collection. 当一个或多个线程在集合上进行迭代时,您应该使用故障安全迭代器,在这两个线程之间,一个线程会更改集合的结构。

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 unsyn; class SyncArrayList实现Runnable {List 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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM