2010-05-21 19 views
32

Vektor ist synchronisiert, ArrayList ist nicht synchronisiert, aber wir können eine ArrayList von Collections.synchronizedList(aList) synchronisieren, so dass die Leistung besser und schneller?Vektor vs Sammlungen.synchronizedList (ArrayList)

+1

Wenn dies C# ist, kennzeichnen Sie Ihre Frage bitte mit "C#" oder ".NET". – FrustratedWithFormsDesigner

+1

Warum schreibst du nicht einen Test und findest es heraus? – skaffman

+0

Können Sie das Nutzungsmuster erklären? 1) Viele schreibt/viele liest 2) Einige schreibt, viele liest, 3) Viele schreibt, wenige liest 4) wenige/wenige braucht keine Optimierung – TJR

Antwort

4

Synchronisierte Sammlungen sind Zeitverschwendung und gefährlich. Ein triviales Beispiel, warum sie schlecht sind, ist zwei Threads betrachten auf der gleichen Sammlung eine Schleife zur gleichen Zeit ausgeführt wird:

int i = 0; 
while (i < list.size()) 
{ 
    if (testSomeCondition(list.get())) { 
    list.remove(i); 
    else 
    i++; 
} 

Unsere Liste synchronisiert werden können (zum Beispiel ein Vektor) und dieser Code würde immer noch schrecklich brechen. Warum? Da die einzelnen Aufrufe von size(), get(), remove(), synchronisiert werden, kann ein Thread dennoch Elemente aus der Liste entfernen, während der andere darüber iteriert. Mit anderen Worten, wir haben eine Race Condition und die Verwendung von synchronisierten Sammlungen hat uns nichts gebracht.

Um das Rennen zu beheben, müssen wir die gesamte Operation auf der Sammlung synchronisieren oder Java 5 Concurrency Locks verwenden, um das gleiche zu tun.

Dieser Codeblock ist jetzt threadsicher, da nur ein Thread die Schleife gleichzeitig ausführen kann. Und jetzt gibt es keinen Grund, eine synchronisierte Sammlung zu verwenden. Wir können eine ArrayList anstelle eines Vektors verwenden und uns die Leistungseinbußen für alle diese synchronisierten Aufrufe sparen.

Verwenden Sie keine synchronisierten Sammlungen. Wenn Sie feststellen, dass mehrere Threads auf dieselbe Liste treffen, müssen Sie die Vorgänge in der Liste schützen, nicht die einzelnen Aufrufe.

+9

"Synchronisierte Sammlungen sind eine Verschwendung von Zeit." -- zu allgemein. Synchronisierte Sammlungen haben einen Zweck. Sie geben nur ein Beispiel, wie man sie falsch benutzt. Strohmann-Argument. – thejoshwolfe

+0

Sie sind buchstäblich eine Zeitverschwendung. Das synchronisierte Schlüsselwort führt zu einem Anrufstrafenabsturz, auch wenn die Sammlung ausschließlich von einem einzelnen Thread verwendet wird. Und die meisten Sammlungen würden ausschließlich von einem einzigen Thread verwendet werden. Und selbst wenn sie geteilt werden, erlaubt das Synchronisieren eines einzelnen Anrufs immer noch Race-Bedingungen, so dass sie nicht für den Zweck geeignet sind. Der Entwickler vergeudet seine Zeit damit, Fehler in seinen vermeintlich threadsicheren Sammlungen zu finden. Einfach ausgedrückt, diese Sammlungen sind giftig und sollten niemals verwendet werden, außer wenn sie nicht vermieden werden (z. B. Legacy-Fälle, J2ME usw.). – locka

+1

Die Synchronisation war in Java 1.3 und früher langsam. In modernen Java ist es besser. http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html Auch wieder mit strohbeladenen Argumenten. Niemand verwendet die Synchronisation mit einer Situation, von der bekannt ist, dass sie single-threaded ist. Ihr erstes Beispiel ist einfach schlechtes Programmieren und keine Sammlung kann das jemals wieder wettmachen. Sie müssen einfach daran denken, was atomar ist oder nicht, unabhängig davon, welche Sammlung Sie verwenden. Sehen Sie sich den Code remove() in ArrayList an und Sie werden sehen, warum diese Methode synchronisiert werden muss, um die Integrität der Liste zu erhalten. – Gus