Вопрос

Этот код будет выдвинуть исключение параллельной модификации, если список изменен в dosomething (). Можно ли избежать этого, заключив код в какой -то синхронизированный блок?

List l = Collections.synchronizedList(new ArrayList());

// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
  doSomething(i.next());
}
Это было полезно?

Решение

  • Если вы удаляете элемент из списка, вы можете сделать это, позвонив, позвонив iterator.remove() вместо list.remove(iterator.next())

  • Если вы добавляете элемент - ну, создайте копию итерационного списка и добавьте его там

  • Если приведенный выше код является частью того же метода, то вам не нужен синхронизированный список или синхронизированные блоки - ни один другой поток не может получить доступ к локальному списку.

Другие советы

Ты Можно изменить Collection Итерация над этим, если вы сделаете это через Iterator интерфейс. Вы можете использовать Iterator.remove() удалить элементы.

Вы не можете изменить его, пока вы итерации над этим. Синхронизация здесь не поможет.

РЕДАКТИРОВАТЬ: Я забыл, что у итератора есть remove метод Так что можно удалить.

Я согласен с другими о Iterator а также remove().


О синхронизации я хотел добавить, что синхронизация предназначена для управления взаимодействиями между разными потоками.

Это типично, чтобы объект синхронизировал несколько методов, и этот один назвал другим. Таким образом, языковые дизайнеры решили, что та же нить не будет заблокирован самим самим в синхронизированном.

Кроме того, думая об этом, это заблокирована нить в ожидании себя, у вас есть великолепный голод перспектива! ;-)

Таким образом, это отвечает на один из ваших вопросов: невозможно избежать проблемы, синхронизируя ваш код.

Использовать CopyOnWriteArrayList вместо синхронизированного списка массивов

List l = Collections.synchronizedList(new ArrayList());

synchronized(l) { 
   // normal iteration -- can throw ConcurrentModificationException
   // may require external synchronization
   for (Iterator i=list.iterator(); i.hasNext(); ) {
      doSomething(i.next());
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top