/ / Iterator Concurrent Modifiction Exception - Java, виняток, ітератор, колекції, синхронізовані

Iterator Concurrent Modifiction Exception - java, виключення, ітератор, колекції, синхронізовані

Цей код видасть виняток паралельної модифікації, якщо список змінено у 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());
}

Відповіді:

7 для відповіді № 1
  • якщо ви вилучаєте елемент зі списку, ви можете зробити це, зателефонувавши iterator.remove() замість list.remove(iterator.next())

  • якщо ви додаєте елемент - ну, створіть копію повторного списку і додайте його туди

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


3 для відповіді № 2

ви може змінити a Collection переглядаючи його, якщо ви робите це через Iterator інтерфейс. Можна використовувати Iterator.remove() для видалення елементів.


0 для відповіді № 3

Ви не можете змінити його під час ітерації. Синхронізація тут не допоможе.

EDIT: Я забув, що у ітератора є файл remove метод. Тож можна видалити.


0 для відповіді № 4

Я погоджуюсь з іншими щодо Iterator і remove().


Щодо синхронізації, я хотів додати, що синхронізація призначена для управління взаємодіями між різними нитками.

Для об’єкта характерно мати декількаметоди синхронізовані, і що один буде викликати інший. Тому дизайнери мови вирішили, що той самий потік не буде заблокований ним самим при синхронізації.

Також, задумавшись, це нитка заблокована, чекаючи на себе, у вас чудова голодування перспектива! ;-)

Отже, це відповідає на одне з ваших запитань: неможливо уникнути проблеми, синхронізуючи ваш код.


0 для відповіді № 5

Використовуйте CopyOnWriteArrayList замість синхронізованого списку масивів


0 для відповіді № 6
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());
}
}