Sunday, June 14, 2009

Concorrência - Iterar HashSet

Na sequência um exemplo de código que encapsula acesso a um HashSet de forma segura (nem tanto...):

public class IteracaoVulneravel {

  private Set palavras = new HashSet();

  public synchronized void removePalavra(String palavra) {
    palavras.remove(palavra);
  }

  public synchronized void addPalavra(String palavra) {
    palavras.add(palavra);
  }

  //pode lançar java.util.ConcurrentModificationException
  public void print() {
    System.out.println("Palavras = "+palavras);
  }
}

O detalhe fica no método print, o compilador implicitamente cria código para navegar na coleção usando o Iterator, para realizar o print dos elementos.
Durante a iteração no elementos ninguém garante que uma outra thread acione o método addPalavra. Caso isso aconteça uma java.util.ConcurrentModificationException será lançada!

Para evitar isso o recomendado seria sincronizar a coleção, veja.

Interessante observação do livro Java Concurrency in Practice.

No comments: