2013-05-24 2 views
3

Мы создаем древовидную структуру, состоящую из AID из структур JADE Agent. Мы решили сделать это рекурсивно, чтобы код мог выполняться независимо от того, сколько агентов в настоящее время находится в системе, древовидная структура может быть динамически изменена, чтобы соответствовать количеству агентов, находящихся в настоящее время в системе. Я не уверен, что необходимо установить какой-то замок, чтобы убедиться, что объект Map считывается и записывается без ущерба целостности структуры.ConcurrentModificationException при рекурсивном использовании Maps в Java

Вот код, вызывающий проблему.

// BuildHierarchy method used to create the hierarchy based on Monitor Agents in the system 
private void BuildHierarchy(Map<AID, Double>freqList, ArrayList<AID> childless, DefaultMutableTreeNode node){ 
    int i = 0; 
    //creates an iterator for the freqList 
    Iterator iter = freqList.entrySet().iterator(); 

    while(iter.hasNext()&& i < 2){ 

     Map.Entry pairs = (Map.Entry)iter.next(); 
     //if (i<2){ 
      setParentNode((AID)pairs.getKey(), node); 
     //} 
     freqList.remove(pairs.getKey()); 
     i++; 
    } 
    BuildHierarchy(freqList, childless, node.getNextNode()); 
    BuildHierarchy(freqList, childless, node.getNextNode().getNextSibling()); 

} 

ответ

2

Вы не можете изменить Set (или лежащей в основе Map) в то время как вы итерацию над ним, за исключением собственной remove операции итератора, или же ConcurrentModificationException будет брошен. Попробуйте

iter.remove(); 

вместо

freqList.remove(pairs.getKey()); 
+0

Спасибо за совет. Это решило проблему. – user2418729

0

Когда итератор создается за реализованную коллекцию набор основы создается на нем и есть счетчик, который ведет учет реализованного размера сбора. Во время итерации, если набор изменен, произнесите «freqList.remove (pairs.getKey()); то он удалит элемент, а размер набора будет уменьшен, и теперь, когда в следующий раз, когда итератор вызовет следующую() операцию на нем, он почувствует, что набор был изменен из экземпляра счетчика и выбрасывает исключение ConcurrentModificationException. Следующий код для класса HashIterator даст вам четкое представление о том, как она работает

 final Entry<K,V> nextEntry() { 
     if (modCount != expectedModCount) 
      throw new ConcurrentModificationException(); 
     Entry<K,V> e = next; 
     if (e == null) 
      throw new NoSuchElementException(); 

     if ((next = e.next) == null) { 
      Entry[] t = table; 
      while (index < t.length && (next = t[index++]) == null) 
       ; 
     } 
     current = e; 
     return e; 
    } 

если запись удаляется с помощью фактического сбора затем modcount! = ExpectedCount будет верно и он будет бросать исключение.

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