746 Stimmen

Warum gilt die Java-Klasse Vector (und Stack) als veraltet oder veraltet?

Warum gilt Java Vector als veraltete Klasse, die veraltet oder veraltet ist?

Ist seine Verwendung nicht gültig, wenn man mit Gleichzeitigkeit arbeitet?

Und wenn ich Objekte nicht manuell synchronisieren und nur eine thread-sichere Sammlung verwenden möchte, ohne dass ich neue Kopien des zugrunde liegenden Arrays erstellen muss (wie CopyOnWriteArrayList tut), dann ist es in Ordnung, die Vector ?

Was ist mit Stack , die eine Unterklasse von Vector Was sollte ich stattdessen verwenden?

719voto

Jon Skeet Punkte 1325502

Vector synchronisiert sich bei jedem einzelnen Vorgang. Das ist fast nie das, was Sie tun wollen.

Im Allgemeinen möchten Sie eine gesamte Sequenz von Operationen. Die Synchronisierung einzelner Operationen ist sowohl weniger sicher (wenn Sie über eine Vector müssen Sie beispielsweise eine Sperre aufheben, um zu verhindern, dass andere Personen die Sammlung gleichzeitig ändern, was zu einer ConcurrentModificationException im iterierenden Thread), aber auch langsamer (warum sollte man eine Sperre wiederholt aufheben, wenn es auch einmal reicht)?

Natürlich hat es auch den Nachteil, dass man auch dann sperren kann, wenn man es nicht braucht.

Im Grunde genommen ist dies in den meisten Situationen ein sehr fehlerhafter Ansatz für die Synchronisierung. Wie Herr Brian Henk darauf hingewiesen, können Sie eine Sammlung mit Aufrufen wie Collections.synchronizedList - die Tatsache, dass Vector kombiniert sowohl die "resized array"-Sammlungsimplementierung mit dem "synchronize every operation"-Bit ist ein weiteres Beispiel für schlechtes Design; der Dekorationsansatz bietet eine sauberere Trennung der Anliegen.

Wie bei einem Stack Äquivalent - ich würde mich umsehen Deque / ArrayDeque um damit zu beginnen.

91voto

Justin Punkte 4349

Vector war Teil von 1.0 - die ursprüngliche Implementierung hatte zwei Nachteile:

1. Benennung: Vektoren sind eigentlich nur Listen, auf die wie Arrays zugegriffen werden kann, also hätte es heißen müssen ArrayList (das ist der Java 1.2 Collections-Ersatz für Vector ).

2. Gleichzeitigkeit: Alle der get() , set() Methoden sind synchronized Daher können Sie die Synchronisierung nicht genau steuern.

Es gibt keinen großen Unterschied zwischen ArrayList y Vector verwenden, sondern Sie sollten ArrayList .

Aus dem API-Dokument.

Ab der Java 2 Plattform v1.2 wurde diese Klasse nachgerüstet und implementiert nun die List-Schnittstelle implementiert, was sie zu einem Mitglied der des Java Collections Frameworks. Im Gegensatz zu den neuen Sammlungsimplementierungen, ist Vector synchronisiert.

43voto

Yishai Punkte 87548

Neben den bereits genannten Antworten zur Verwendung von Vector hat Vector auch eine Reihe von Methoden zur Aufzählung und zum Abrufen von Elementen, die sich von der List-Schnittstelle unterscheiden, und Entwickler (insbesondere diejenigen, die Java vor 1.2 gelernt haben) können dazu neigen, sie zu verwenden, wenn sie im Code vorhanden sind. Obwohl Enumerationen schneller sind, prüfen sie nicht, ob die Sammlung während der Iteration geändert wurde, was zu Problemen führen kann, und da Vector wegen seiner Syncronisierung - mit dem damit verbundenen Zugriff von mehreren Threads - gewählt werden könnte, ist dies ein besonders schädliches Problem. Die Verwendung dieser Methoden bindet auch eine Menge Code an Vector, so dass es nicht einfach sein wird, sie durch eine andere List-Implementierung zu ersetzen.

16voto

200_success Punkte 6986

java.util.Stack erbt den Synchronisations-Overhead von java.util.Vector , was in der Regel nicht gerechtfertigt ist.

Es erbt aber noch viel mehr. Die Tatsache, dass java.util.Stack extends java.util.Vector ist ein Fehler im objektorientierten Design. Puristen werden bemerken, dass er auch viele Methoden bietet, die über die traditionell mit einem Stack verbundenen Operationen hinausgehen (nämlich: push, pop, peek, size). Es ist auch möglich, Folgendes zu tun search , elementAt , setElementAt , remove und viele andere Zufallszugriffsoperationen. Es ist grundsätzlich Sache des Benutzers, auf die Verwendung der Nicht-Stapel-Operationen von Stack .

Aus diesen Gründen der Leistung und des OOP-Designs ist die JavaDoc für java.util.Stack empfiehlt ArrayDeque als natürlichen Ersatz. (Ein Deque ist mehr als ein Stack, aber zumindest ist es auf die Manipulation der beiden Enden beschränkt, anstatt zufälligen Zugriff auf alles zu bieten.)

15voto

Brian Henk Punkte 615

Sie können die synchronizedCollection/Liste Methode in java.util.Collection um eine thread-sichere Sammlung aus einer nicht-thread-sicheren Sammlung zu erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X