Pergunta

Preciso sincronizar isso, quando muitos threads acessando o método get e apenas um thread está acessando o método setlist?

public class ListContainer {
  private List<String> myList = new ArrayList<String();

  public List<String> get ( )
  {
    return new ArrayList<String>(myList);
  }

  public List<String> set ( )
  {
    this.myList = computeList();
  }
}

Não me importo se os leitores obtiverem dados antigos, mas os dados devem ser consistentes.

Janning

Foi útil?

Solução

Você não precisa sincronizar (mas deve declarar myList Como volatile) Se as seguintes condições forem verdadeiras:

  • computeList não depende do estado atual de myList
  • Você não altera o conteúdo da lista depois que ela foi atribuída (Collections.unmodifiableList(computeList()) é a melhor maneira de expressar essa condição)

Outras dicas

Não, você não precisa de sincronização. Não há modificações simultâneas (se computeList() não depende do myList).

btw, por que você está voltando new ArrayList(myList) Em vez de simplesmente voltar myList?

Não importa se o Computelist depende da MyList ou não, desde que haja apenas o acesso ao conteúdo do MyList, não pode surgir um problema de sincronização.

Se não estiver usando volátil para mylist, pode ocorrer que retorne a antiga mylist, mesmo que o conjunto estritamente já tenha substituído a lista. Se você não se importa com essa situação (isso pode levar a dois threads vendo valores diferentes), você não precisa de voláteis.

Eu prefiro fazer a cópia implícita por

public class ListContainer {

    private final List<String> myList = new CopyOnWriteArrayList<String>();

    public List<String> get (){
      return myList;
    }

    public List<String> set (){
       computeList();
    }
}

Hth

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top