Muitos leitores, um escritor: preciso sincronizar isso?
-
22-09-2019 - |
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
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 demyList
- 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