2016-03-17 2 views
3

У меня есть массив, который я разделяю между двумя потоками, и я пытаюсь перебрать и изменить список в одно и то же время. Я не хочу использовать метод итератора, и я также использовал синхронизированный список, но он все еще дает concurrentmodificationexception.Как изменить и изменить этот Arraylist?

код выглядит следующим образом:

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

} 
+0

Этот код должен бросить 'NullPointerException' на линии' Список несинхр = Collections.synchronizedList (unsyn) ', так как' unsyn' равно нулю. –

+0

Я не могу отредактировать свой вопрос .. Кажется, что некоторая ошибка рассмотрит «Список unsync' в качестве первой строки – Amol

ответ

1

javadoc для Collections.synchronizedList(...) объясняет то, что вам нужно сделать:

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

В многопоточной среде вы должны рассмотреть возможность использования CopyOnWriteArrayList, который не производит ConcurrentModificationException

0

Итератор, который вы используете, - это быстрый итератор. Быстрое итератор считывает внутреннюю структуру данных напрямую. Внутренняя структура данных не должна изменяться при повторении через коллекцию.

Вы должны использовать Fail-safe iterator, когда один или несколько потоков итерации по коллекции, между ними, один поток изменяет структуру коллекции.

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"); 
} 
Смежные вопросы