2010-01-27 28 views

Antwort

4

Vector wird als "Thread-sicher" betrachtet, da der Zugriff auf die Interna des Vectors synchronisiert wird. Methoden wie add(), get(), size() usw. werden alle so synchronisiert, dass Änderungen an der internen Struktur des Vector und Zugriff auf diese interne Struktur nicht gleichzeitig von separaten Threads verarbeitet werden können.

16

Es wird "thread-safe" gemacht, indem alle Methoden synchronisiert werden (über das synchronisierte Schlüsselwort), siehe OpenJDK source code.

Durch das synchronisierte Schlüsselwort wird verhindert, dass mehr als ein Thread synchronisierte Methoden gleichzeitig ausführt. Es verwendet intern eine Sperre, die ein Thread beim Eingeben dieser Methoden erhalten muss, und die der Thread freigibt, wenn er die Methode verlässt.

Beachten Sie, dass dies nicht wirklich viel hilft, da es zwar einen inkonsistenten internen Zustand des Vektors verhindert, dies jedoch in keiner Weise eine Konsistenz auf einer höheren Ebene garantiert (eine nützliche Ebene für eine Anwendung).

Betrachten Sie dieses Beispiel, das zeigt, dass Sie immer noch die Synchronisation im Anwendungscode verwenden müssen (so dass Sie könnte genauso gut die unsynchronisierte Arraylist verwendet haben):

// BROKEN CODE, needs external synchronization 
// only add an element if the vector is empty 
if(vector.isEmpty()) 
    vector.add(anElement); 
+0

+1, aber Sie sollten korrigieren "Was das synchronisierte Schlüsselwort bewirkt, ist, dass es mehr als einen Thread daran hindert, die Methode zur gleichen Zeit auszuführen". Es ist nicht nur der Zugriff auf die bestimmte Methode, die blockiert ist. – Fredrik

+0

@ Fredrik: Danke. Ich habe versucht, den Satz zu reparieren, ohne dass es zu komplex wurde. Ich nehme an, ein Link zu einer längeren Erklärung wäre in Ordnung. – Thilo

+0

Habe ich es richtig verstanden, dass in dem Code, den Sie zur Verfügung gestellt haben, der "Vektor" vor vector.add (anElement) verändert worden sein könnte (nicht leer); – soshial

0

Bitte finden Sie die folgenden Auszüge aus java api

Erstens ist es nicht möglich, dass zwei Aufrufe synchronisierter Methoden auf dasselbe Objekt verschachtelt werden. Wenn ein Thread eine synchronisierte Methode für ein Objekt ausführt, werden alle anderen Threads aufgerufen, die synchronisierte Methoden für denselben Objektblock aufrufen (Ausführung aussetzen), bis der erste Thread mit dem Objekt ausgeführt wird.

Zweitens, wenn eine synchronisierte Methode beendet wird, stellt sie automatisch eine "happen-before" -Beziehung mit einem nachfolgenden Aufruf einer synchronisierten Methode für dasselbe Objekt her. Dies garantiert, dass Änderungen am Status des Objekts für alle Threads sichtbar sind.