Viele Leser, ein Autor: Muss ich dies synchronisieren?
-
22-09-2019 - |
Frage
brauche ich dies zu synchronisieren, wenn viele Threads die get-Methode und nur einen Thread Zugriff wird die Setlist Methode zugreifen?
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();
}
}
ist mir egal, wenn Leser alte Daten erhalten, aber die Daten konsistent sein.
Janning
Lösung
Sie haben nicht zu synchronisieren (aber Sie müssen myList
als volatile
erklären), wenn folgende Bedingungen erfüllt sind:
-
computeList
hängt nicht von dem aktuellen Stand dermyList
- Sie ändern sich nicht Inhalt der Liste, nachdem er zugeordnet wurde (
Collections.unmodifiableList(computeList())
ist der bessere Weg, um diesen Zustand zu exprimieren)
Andere Tipps
Nein, Sie müssen nicht dort Synchronisation. Es gibt keine irgendwelche gleichzeitige Änderungen (wenn computeList()
tut auf der myList
abhängt).
btw, warum kehren Sie new ArrayList(myList)
anstatt einfach myList
zurückkehren?
Es spielt keine Rolle, ob computeList hängt von myList oder nicht, solange es nur lesenden Zugriff auf den Inhalt von myList kein Synchronisationsproblem entstehen kann.
Wenn nicht flüchtig mit für myList dann könnte es sein, dass get kehrt den alten myList auftreten, obwohl streng hat bereits die Liste ersetzt. Wenn Sie nicht über diese Situation kümmern (es könnte zu zwei Threads führen unterschiedliche Werte zu sehen), dann brauchen Sie nicht flüchtig.
Ich würde lieber tun das Kopieren implizit durch
public class ListContainer {
private final List<String> myList = new CopyOnWriteArrayList<String>();
public List<String> get (){
return myList;
}
public List<String> set (){
computeList();
}
}
HTH