2015-08-21 5 views
1

У меня есть переменная частный класс, он объявлен какConcurrentModificationException когда итерация по списку

private List<String> list= new ArrayList<String>(); 

Мое приложение выдает java.util.ConcurrentModificationException, когда несколько потоков пытаются перебрать список

for (Iterator i = list.iterator(); i.hasNext();){ 
    System.out.println(i.next()+"\n"); 
} 

Я ищу за советы, чтобы избежать этой проблемы с минимальными изменениями. Эта переменная класса является общей и используется несколькими методами в этом классе.

ответ

0

Поскольку у вас уже есть ключ к тому, что к списку будут доступны несколько потоков, объявите поточный сейф List.

List<String> list= Collections.synchronizedList(new ArrayList<String>()); 
+0

Учитывая Javadocs звучит как ОП нужно будет также явно синхронизировать с помощью синхронизированных ключевое слово. Поэтому просто изменить переменную для использования Collections.synchronizedList может быть недостаточно. – KumarM

1

При использовании iterator на Collection, вы должны использовать iterator.remove() и не Collection.remove() предотвратить ConcurrentModificationException. Однако, если у вас есть несколько потоков, вам может понадобиться также использовать Collections.syncrhonizedList().

Из Oracle Java Docs:

List list = Collections.synchronizedList(new ArrayList()); 
    ... 
synchronized (list) { 
    Iterator i = list.iterator(); // Must be in synchronized block 
    while (i.hasNext()) 
     foo(i.next()); 
} 
+0

Спасибо за ответ, но я думаю, что дал неправильное направление. Таким образом, желаемый сценарий - это когда несколько потоков обращаются к этому классу, каждый из которых использует список для хранения и получения собственных вычислений. В настоящее время приватный список list = new ArrayList (); разместит список в куче, который будет использоваться несколькими потоками. Я хотел бы, чтобы у каждого из потоков была своя копия списка. Но мы получаем исключение ConcurrentModificationException с текущей реализацией. – enfany

+0

Я не совсем понимаю, что вы подразумеваете под каждым потоком, имеет свою собственную копию списка. Когда один поток хранит что-то новое, если он обновляется в других потоках? –

+0

Каждый поток будет хранить разные результаты в этом списке (потому что другой метод в этом классе вызывается каждым потоком, который снова инициализирует список с новым ArrrayList). Мы хотим сделать эту переменную класса локальной для каждого потока вместо совместного использования несколькими потоками. – enfany

1

Вы можете попробовать CopyOnWriteList, JavaDocs сказать:

Этот массив не меняется в течение жизни итератора, поэтому вмешательство невозможно, и итератор гарантированно не бросать ConcurrentModificationException.

List<String> list = new CopyOnWriteArrayList<>(); 
+0

Если большая часть активности написана, есть ли у нас альтернативная структура для обеспечения безопасности потоков, а также исключения исключения одновременной модификации? – enfany

Смежные вопросы