Frage

Ich brauche eine Arraylist von Arraylisten machen fädelt sicher. Ich kann auch nicht die Client-Änderungen an der Sammlung. Wird die unveränderbare Wrapper es sicher fädeln oder brauche ich zwei Wrapper für die Sammlung?

War es hilfreich?

Lösung

Es hängt davon ab. Der Wrapper wird nur verhindern, dass Änderungen an der Sammlung es Wraps, nicht auf die Objekte in der Sammlung. Wenn Sie eine Arraylist von Arraylists, die globale Liste sowie jede seiner Elementlisten müssen separat gewickelt werden, und Sie können auch etwas für den Inhalt dieser Listen zu tun haben. Schließlich müssen Sie sicherstellen, dass die ursprüngliche Liste Objekte nicht geändert werden, da nur die Wrapper-Änderungen durch die Wrapper-Referenz verhindert, nicht auf das ursprüngliche Objekt.

Sie brauchen nicht auf den synchronisierten Wrapper in diesem Fall.

Andere Tipps

Auf einem verwandten Thema - ich mehrere Antworten gesehen habe was darauf hindeutet, mit synchronisierten Sammlung, um Thread-Sicherheit zu erreichen. nicht synchronisierte Version einer Sammlung unter Verwendung nicht macht es „Thread-sicher“ - obwohl jede Operation (Einfügen, zählt etc.) wird durch Mutex geschützt, wenn zwei Operationen kombiniert es keine Garantie dafür gibt, dass sie atomar ausführen würden. Beispielsweise der folgende Code ist nicht sicher Gewinde (auch mit einer synchronisierten queue):

if(queue.Count > 0)
{
   queue.Add(...);
}

Die unmodifiable Wrapper verhindert nur Änderungen an der Struktur der Liste, die es gilt. Wenn diese Liste weitere Listen enthält und Sie haben versucht, Fäden diese verschachtelten Listen zu ändern, dann geschützt sind Sie nicht gegen gleichzeitige Änderung Risiken.

an der Sammlungen Quelle Vom Blick sieht es aus wie Unmodifiable hat nicht es synchronisiert werden.

static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                 implements Set<E>, Serializable;

static class UnmodifiableCollection<E> implements Collection<E>, Serializable;

die synchronisierten Klassenwrapper haben ein Mutex-Objekt in ihnen die synchronisierten Teile zu tun, so sieht aus wie Sie beide verwenden, müssen beide zu bekommen. Oder rollen Sie Ihre eigenen!

Ich glaube, dass, weil die UnmodifiableList Wrapper speichert die Arraylist zu einem letzten Feld, werden alle Lesemethoden auf der Verpackung wird die Liste sehen, wie es war, wenn die Verpackung so lange gebaut wurde als die Liste nicht modifiziert wird, nachdem der Wrapper erstellt wird und solange die wandelbar Arraylisten innerhalb der Verpackung nicht verändert werden (die die Umhüllung gegen nicht schützen kann).

Es wird Thread-sicher sein, wenn die unveränderbare Ansicht sicher veröffentlicht wird, und das modifizierbare Original nie geändert wird (einschließlich allen Objekte rekursiv in der Sammlung enthalten!) Nach der Veröffentlichung der unmodifiable Ansicht.

Wenn Sie die ursprüngliche Modifikation behalten mögen, dann können Sie entweder eine defensive Kopie der Objekt Grafik Ihrer Sammlung erstellen und geben einen unveränderbaren Blick auf das, oder eine inhärente Thread-sichere Liste verwenden, um mit zu beginnen, und kehren eine unmodifiable Ansicht davon.

Sie nicht Rückkehr ein unmodifiableList (synchonizedList (theList)), wenn Sie nach wie vor die Absicht, theList unsynchronisierten zuzugreifen danach; wenn wandelbarer Zustand zwischen mehreren Threads gemeinsam genutzt wird, dann alle Gewinde müssen synchronisieren auf der gleiche Sperren, wenn sie Zugriff auf diesem Zustand.

Ein unveränderliches Objekt ist per Definition Thread-sicher (niemanden unter der Annahme, behält Verweis auf die Original-Sammlungen), so Synchronisation ist nicht erforderlich.

Wrapping die äußere Arraylist mit Collections.unmodifiableList () verhindert, dass der Client von seinem Inhalt (und damit ändert macht es fädeln Safe), aber die inneren Arraylisten sind noch wandelbar.

Das Umwickeln der inneren Arraylisten mit Collections.unmodifiableList () zu verhindert, dass der Kunde von ihrem Inhalt zu verändern (und damit macht sie Threadsicherheit), das ist, was Sie brauchen.

Lassen Sie uns wissen, ob diese Lösung verursacht Probleme (Overhead, Speichernutzung usw.); andere Lösungen können, um Ihr Problem anwendbar sein. :)

EDIT: Natürlich, wenn die Listen geändert werden, werden sie nicht Thread-sicher. Ich nahm keine weiteren Änderungen vorgenommen werden sollten.

Nicht sicher, ob ich verstand, was Sie zu tun versuchen, aber ich würde sagen, dass die Antwort in den meisten Fällen ist „Nein“.

Wenn Sie Setup eine Arraylist von Arraylist und beide, die äußeren und inneren Listen können nie nach der Erstellung (nur ein Thread und bei der Erstellung wird der Zugang zu entweder inneren und äußeren Listen) geändert werden, werden sie fädeln wahrscheinlich durch einen Wrapper sicher (wenn beide, Außen und Innenlisten derart gewickelt sind, dass sie modifiziert ist unmöglich). Alle Nur-Lese-Operationen auf Arraylists sind höchstwahrscheinlich Thread-sicher. Sun hat jedoch nicht Garantie sie Thread-sicher (auch für Nur-Lese-Operationen nicht) sein, so dass, obwohl es jetzt funktionieren könnte, es in Zukunft brechen könnte (wenn Sun einig internen erstellt Caching von Daten für einen schnelleren Zugriff zum Beispiel).

Dies ist nötig, wenn:

  1. Es ist noch ein Verweis auf die ursprüngliche modifizierbare Liste.
  2. Die Liste wird möglicherweise obwohl Iterator zugegriffen werden.

Wenn Sie von der Arraylist von Index zu lesen beabsichtigen, nur konnte man davon ausgehen, das ist Thread-sicher.

Im Zweifelsfall den synchronisierten Wrapper gewählt hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top