Параллельное исключение модификации

Ассоциативный? Не без некоторой работы, но можно использовать универсальные селекторы:

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});
8
задан Cambium 7 July 2009 в 00:25
поделиться

12 ответов

Если вы создали LinkedHashMap с accessOrder = true, то LinkedHashMap.get () фактически изменяет LinkedHashMap, поскольку он сохраняет последнюю доступную запись в начале связанного списка записей. Возможно, что-то вызывает get (), пока список массивов копирует его с помощью Iterator.

7
ответ дан 5 December 2019 в 10:43
поделиться

Are those all function you have in your wrapper? Because this exception could be thrown while you somehow iterating over collection in another place. And I guess you synchronized method with potential obvious race condition, but probably have missed less obvious cases. Here the reference to exception class docs.

2
ответ дан 5 December 2019 в 10:43
поделиться

This exception does not normally have anything to do with synchronization - it is normally thrown if a a Collection is modified while an Iterator is iterating through it. AddAll methods may use an iterator - and its worth noting that the posh foreach loop iterates over instances of Iterator too.

e.g:

for(Object o : objects) {
    objects.remove(o);
}

is sufficient to get the exception on some collections (e.g ArrayList).

James

6
ответ дан 5 December 2019 в 10:43
поделиться

Я не думаю, что ваш set () / get () синхронизируются с тем же монитором, что и rebuild () . Это позволяет кому-то вызывать set / get во время выполнения проблемной строки, особенно при итерации по набору ключей internalMap во время вызова addAll () (внутренняя реализация, которая отображается через трассировку стека).

Вместо синхронизации set () , Вы пробовали что-то вроде:

public void set(SomeKey key, SomeValue val) {
    synchronized(this) {
        internalMap.put(key, val); // or whatever your get looks like
    }
}

Я не думаю, что вам вообще нужно синхронизировать get () , но если вы настаиваете:

public SomeValue get(SomeKey key) {
    synchronized(this) {
        internalMap.get(key); // or whatever your get looks like
    }
}

На самом деле, я думаю, что вам лучше отключена синхронизация с internalMap вместо this . Также не помешает сделать internalMap volatile , хотя я не думаю, что это действительно необходимо, если вы уверены, что set () / get () / rebuild () - единственные методы, напрямую обращающиеся к internalMap, и все они получают доступ к нему синхронизированным образом.

private volatile Map internalMap ...
0
ответ дан 5 December 2019 в 10:43
поделиться

Из Javadoc:

Если несколько потоков обращаются к связанной хэш-карте одновременно, и хотя бы один из потоков структурно модифицирует карту, она должна быть синхронизирована извне. Обычно это достигается путем синхронизации некоторого объекта, который естественным образом инкапсулирует карту. Если такого объекта не существует, карту следует «обернуть» с помощью метода Collections.synchronizedMap. Лучше всего это делать во время создания, чтобы предотвратить случайный несинхронизированный доступ к карте:

Map m = Collections.synchronizedMap (new LinkedHashMap (...));

Для вас может быть безопаснее фактически обернуть LinkedHashMap вместо того, чтобы требовать от вас расширения. Таким образом, ваша реализация будет иметь внутренний элемент данных, который является картой, возвращаемой Collections.synchronizedMap (new LinkedHashMap (...)).

Подробности см. В документации по коллекциям: Collections.synchronizedMap

1
ответ дан 5 December 2019 в 10:43
поделиться

Является ли internalMap статическим? У вас может быть несколько объектов, каждый из которых блокируется на this , объект, но не обеспечивает правильную блокировку на вашем static internalMap.

0
ответ дан 5 December 2019 в 10:43
поделиться

Try removing the synchronized keyword from the set() and get() methods, and instead use a synchronized block inside the method, locking on internalMap; then change the synchronized blocks on the rebuild() method to lock on the internalMap as well.

0
ответ дан 5 December 2019 в 10:43
поделиться

that is strange. I cant see any way that the exception is being thrown at the location you are identifying (in the default implmentation in Java 6). are you getting a ConcurrentModificationException in the ArrayList or the HashMap? have you overridden the keySet() method in your HashMap?

edit my mistake - the ArrayList will force the KeySet to iterate (AbstractCollection.toArray() will iterate over its keys)

there is somewhere in the code that is allowing you to update your internal map that is not synchronized.

  • do you have a utility method that exposes your internal map that "shouldnt be used" or
  • is your internal map identified as public scope
0
ответ дан 5 December 2019 в 10:43
поделиться

Попробуйте объявить карту как временную

0
ответ дан 5 December 2019 в 10:43
поделиться

Во время итерации ключей из-за

keysCopy.addAll(internalMap.keySet());

Вы решили, что некоторые записи могут быть удалены из LinkedHashMap?

Метод removeEldestEntry может быть либо возвращает истину, либо изменяет карту, тем самым нарушая итерацию.

0
ответ дан 5 December 2019 в 10:43
поделиться

попробуйте следующее:

public void rebuild(){
  /* initialization stuff */
  List<SomeKey> keysCopy = new ArrayList<SomeKey>();
  synchronized (internalMap) {
    keysCopy.addAll(internalMap.keySet());
  }
  /* 
    do stuff with keysCopy, update a temporary map
   */    
  synchronized (internalMap) {
    internalMap.putAll(tempMap);
  }
}
0
ответ дан 5 December 2019 в 10:43
поделиться

Сохранить доступ к internalMap syncronized , в противном случае возникает исключение java.util.ConcurrentModificationException, потому что HashMap # modCount (который записывает структурные изменения) может быть изменен одновременно во время итерации набора ключей (из-за keysCopy. addAll (вызов internalMap.keySet ()).

LinkedHashMap javaDoc указывает: «В связанных хэш-картах с упорядоченным доступом простой запрос карты с помощью get является структурной модификацией.»

0
ответ дан 5 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: