Exception in thread “Thread-2” java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at interfaceGrafica.TelaPrinc$Cliente.run(TelaPrinc.java:1030)
Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at interfaceGrafica.TelaPrinc.CriaObjeto(TelaPrinc.java:692)
at interfaceGrafica.TelaPrinc.MontaArvore(TelaPrinc.java:628)
at interfaceGrafica.TelaPrinc.paint(TelaPrinc.java:611)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknow
n Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Segue o trecho de código onde a mensagem acima diz que o erro está:
List usuariosAt;// = new ArrayList();
usuariosAt = null;
SelecionaUsuarios sU = new SelecionaUsuarios();
usuariosAt = sU.Seleciona(agrupamento);
sU = null;
//usuariosAt = new SelecionaUsuarios().SelecionaUsuarios(agrupamento);
Funcionario func = null;
func = new Funcionario();
System.out.println("Atualizando...");
for (Iterator I = usuariosAt.iterator(); I.hasNext();){
[b] func = ((Funcionario) I.next());[/b]
if (func.getStatus().equals("Presente")){
System.out.println(func.getNome());
//System.out.println(func.getID());
System.out.println(func.getStatus());
System.out.println("---------------------------");
}
}
usuariosAt = null;
System.out.println("---------------------------");
pintar = true;
repaint();
Carinha, em qual linha do código que você colocou que acontece o erro?
Provavelmente na segunda vez que tenta dar um .next()?
java.util.ConcurrentModificationException acontece quando você está trabalhando com uma lista, iterando nela e algum outro lugar altera essa lista.
No stack aparece “Thread-2”, no caso, será que essa lista que você obteve não é uma referencia que outro lugar também está utilizando?
Segue um exemplo onde ocorre a exceção:
import java.util.ArrayList;
import java.util.List;
public class TesteConcurrentModification {
public static void main(String[] args) {
List<Integer> minhaLista = new ArrayList<Integer>();
minhaLista.add(1);
minhaLista.add(2);
for (Integer integer : minhaLista) {
// ao entrar no for a lista é alterada, quando tentar dar um próximo .next(),
// ocorre a exceção, pois seu iterator foi alterado.
minhaLista.add(3);
}
}
}
No caso, o erro acontece na linha 12, após entrar no for e dar o primeiro “minhaLista.add(3)”.
Obrigado pelas respostas, não entendi muito bem o porque de não utilizar o Iterator vou ter que pesquisar mais sobre o assunto mas já providênciei a alteração sugerida.
Desconfio onde esteja o problema, no código vocês podem observar que eu obtenho a minha coleção a partir de uma classe chamada SelecionaUsuarios, nessa classe eu tenho uma outra coleção chamada usuarios que é retornada por esta classe que sofre vários Add´s, essa classe é chamada em outros locais no código. Ou seja será que enquanto está rodando o iterator algum outro lugar chamar a classe SelecionaUsuarios vai gerar o erro?
Tipo existe uma relação entre a coleção que está dentro da classe SelecionaUsuarios e a outra coleção que está no Iterator ?
carinha, se a sua classe SelecionaUsuarios retorna usuários naquele momento, acho que daria pra resolver se no método que retorna a lista de usuários retornasse um new ArrayList(suaListaDeUsuarios), assim você iteraria em uma lista nova, e a lista que sofre alterações continuaria na sua classe SelecionaUsuarios. Ou então dentro do seu método criar uma nova lista e dar um addAll, mas tudo isso depende é claro da sua necessidade com relação a essa lista de usuários.
O problema é que em lugares distintos você realiza alterações na mesma referência que foi passada para esse método.
Mas caso uma alteração realizada na lista por outra thread seja algo crucial e implique no resultado esperado, acho que vai ter que utilizar uma lista sincronized mesmo.
Agora entendo o porque da utilização do iterator, agradeço o esclarecimento.
Consegui resolver o problema utilizando Collections.synchronizedList(usuariosAt), pois realmente eu preciso que os dados sejam alterados por outras threads.
Não use Iterator principalmente qdo você está utilizando qualquer tipo de Thread ou fazendo o que fez no loop (adicionar um novo item à lista durante a iteração).
Substitua por um for com um int de controle: for(int i = 0, i < size ; ++i)
E obtenha o item com lista.get(i)
Isso diminui problemas relacionados.
Obs. Se durante a iteração ocorrer tbm de tentar adicionar algum item, vai ocorrer o mesmo erro.
Um bloco sincronizado tbm pode “resolver” o problema.
synchronized(lista){
//Faça o que quiser com a lista mas saiba que pode ocorrer perda de performance.
}
Ou então utilize syncList = Collections.synchronizedList(lista); mas não use iteração do mesmo jeito pois é a única parte não sincronizada :evil:
Observe a API, normalmente o Javadoc dá indicações do problema [google]ConcurrentModificationException 6[/google]
O uso do Iterator de uma coleção “proibe” a classe de ser alterada enquanto houver iterações. Porém permite que o conteúdo de um item exixtente seja modificado.
Durante a iteração, não podemos adicionar um item novo na lista ou exluí-lo sob pena de receber um ConcurrentModificationException.
O mesmo processo utilizando o método get resolve esse problema (entretanto, se você deletar um registro, cuidado para não tentar acessar um item inválido, ou se adicionar um novo, cuidado para não passar batido em alguma situação )
Se não me engano o foreach utiliza internamente de iteração, ou seja, causa o mesmo problema.