Iterando e tomando java.util.ConcurrentModificationException
Eu estava marotamente executando o codigo abaixo, e ele ferverosamente me dropava a seguinte exceção "java.util.ConcurrentModificationException"
public void removeNVE() { List<PrmNVE> lista = ncm.getNves(); for (PrmNVE nve : lista) { if (nve.isSelect()) { lista.remove(nve); } } }
De primeira eu não vi um problema, porem depois de uma leve procurada no "Ohhh Meuuu Phai"(Google), o problema ocorre por eu estar iterando pela lista e tentar remover o objeto atual(Dãã!!), meio obvio neh?
O Iterator da lista, usa um conceito chamado "Fail-Fast", para entendermos esse conceito, precisamos entrar em outros, então:
-Dentro do iterator ele usa um contador, que é agraciado pelo modificador Volatile
-Volatile é uma palavra chave do Java, que quer dizer duas coisas
-O valor da variavel vai ser alterado por multiplas threads
-O valor nunca vai ser cacheado localmente, sempre sera alocado na memoria principal(heap)
-Caso um elemento seja removido da lista, o Iterator ainda terá uma referencia ao objeto e a ConcurrentModificationException, será lançada caso o Iterator tente acessar o ojbeto removido
-Para que isso não ocorra use o metodo remove do Iterator
Como resolver:
List<PrmNVE> lista = new ArrayList<PrmNVE>(ncm.getNves()); for (PrmNVE nve : lista) { if (nve.isSelect()) { ncm.getNves().remove(nve); } } //OU Iterator<PrmNVE> iterator = ncm.getNves().iterator(); while(iterator.hasNext()){ PrmNVE nve = iterator.next(); if(nve.isSelect()) { iterator.remove(); } } //OU int tam = ncm.getNves().size(); for(int i = 0 ; i < tam ; i++) { PrmNVE nve = ncm.getNves().get(i); if(nve.isSelect()) { ncm.getNves().remove(i); } }
Eu indico a primeira solução com o Iterator, pois ela é fail safe e mais elegente.
Comments
Post a Comment