Olá galera. Estava pesquisando sobre a exceção ConcurrentModificationException e encontrei este tópico. Desculpe ressuscitá-lo depois de muito tempo, mas em relação ao que o rmalati questionou:
A questão é a seguinte rmalati: na classe PriorityQueue há um métod next() utilizado pelo iterador para retornar o próximo elemento:
public E next() {
if (expectedModCount != modCount)
throw new ConcurrentModificationException();
if (cursor < size)
return (E) queue[lastRet = cursor++];
if (forgetMeNot != null) {
lastRet = -1;
lastRetElt = forgetMeNot.poll();
if (lastRetElt != null)
return lastRetElt;
}
throw new NoSuchElementException();
}
Há duas variáveis que ele utiliza para controle de modificações: expectedModCount e modCount. Essas duas variáveis ambas vão possuir o mesmo valor caso não haja nenhuma modificação. Como pode ser visto no método poll(), ele incrementa a variável modCount quando é invocado:
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}
Conclusão: A primeira vez que o iterador invocar o método next(), o seguinte teste if (expectedModCount != modCount)
throw new ConcurrentModificationException(); será feito e retornará false, fazendo com que o elemento seja impresso normalmente. Após o método poll() ser executado uma vez, ele irá modificar a variável modCount e a próxima vez que next() for chamado pelo iterador, o teste if (expectedModCount != modCount)
throw new ConcurrentModificationException(); irá retornar true e fará com que lance ConcurrentModificationException.
Espero ter ajudado a esclarecer essa dúvida.