Ich frage mich, welches davon in der Praxis besser ist und warum?
Ich habe festgestellt, dass Lock
und Condition
(und andere neue concurrent
Klassen) nur mehr Werkzeuge für die Toolbox sind. Ich konnte fast alles, was ich brauchte, mit meinem alten Klauenhammer (dem synchronized
Schlüsselwort) tun , aber es war in manchen Situationen umständlich, ihn zu verwenden. Einige dieser unangenehmen Situationen wurden viel einfacher, als ich meinem Werkzeugkasten weitere Werkzeuge hinzufügte: einen Gummihammer, einen Kugelhammer, einen Stemmeisen und einige Nagelstempel. jedoch , mein alter Klauenhammer sieht immer noch seinen Anteil an der Nutzung.
Ich denke nicht, dass einer wirklich "besser" ist als der andere, sondern dass jeder besser für verschiedene Probleme geeignet ist. Kurz gesagt, das einfache Modell und die bereichsorientierte Natur von synchronized
helfen mir, mich vor Fehlern in meinem Code zu schützen, aber dieselben Vorteile sind manchmal Hindernisse in komplexeren Szenarien. Es sind diese komplexeren Szenarien, für deren Behebung das gleichzeitige Paket erstellt wurde. Die Verwendung dieser übergeordneten Konstrukte erfordert jedoch eine explizitere und sorgfältigere Verwaltung des Codes.
===
Ich denke, dass JavaDoc die Unterscheidung zwischen Lock
und gut beschreibt synchronized
(der Schwerpunkt liegt bei mir):
Sperrimplementierungen bieten umfangreichere Sperrvorgänge, als sie mit synchronisierten Methoden und Anweisungen erzielt werden können. Sie ermöglichen eine flexiblere Strukturierung , haben möglicherweise sehr unterschiedliche Eigenschaften und unterstützen möglicherweise mehrere zugeordnete Bedingungsobjekte .
...
Die Verwendung von synchronisierten Methoden oder Anweisungen ermöglicht den Zugriff auf die implizite Monitorverriegelung mit jedem Objekt zugeordnet ist , aber alle Kräfte Lock - Acquisition und Freigabe in einem block strukturiert auftreten : wenn mehrere Schlösser sind erworben sie in umgekehrter Reihenfolge gelöst werden muss , und Alle Sperren müssen in demselben lexikalischen Bereich freigegeben werden, in dem sie erworben wurden .
Während der Scoping-Mechanismus für synchronisierte Methoden und Anweisungen das Programmieren mit Monitorsperren erheblich vereinfacht und dazu beiträgt , viele häufige Programmierfehler bei Sperren zu vermeiden, müssen Sie gelegentlich flexibler mit Sperren arbeiten. Zum Beispiel erfordern * * einige Algorithmen * zum Durchlaufen von Datenstrukturen, auf die gleichzeitig zugegriffen wird , die Verwendung von "Hand-over-Hand" oder "Kettenverriegelung" : Sie erwerben die Sperre von Knoten A, dann Knoten B, geben dann A frei und erwerben C, Lassen Sie dann B los und erwerben Sie D und so weiter. Implementationen der Lock - Schnittstelle , die Verwendung solcher Techniken ermöglichen durch eine Sperre ermöglicht in verschiedenen Bereichen erworben und freigegeben werden , undSo können mehrere Sperren in beliebiger Reihenfolge erworben und freigegeben werden .
Mit dieser erhöhten Flexibilität geht zusätzliche Verantwortung einher . Das Fehlen blockblockierter Sperren beseitigt die automatische Freigabe von Sperren , die bei synchronisierten Methoden und Anweisungen auftritt. In den meisten Fällen sollte die folgende Redewendung verwendet werden:
...
Beim Verriegeln und Entriegeln kommen in verschiedenen Bereichen , Sorgfalt getroffen werden müssen sicherstellen , dass der gesamte Code, der ausgeführt wird , während die Sperre gehalten wird durch geschützt try-finally oder versuchen Beifang zu gewährleisten , dass die Sperre aufgehoben wird , wenn notwendig.
Lock - Implementierungen bieten zusätzliche Funktionalität über die Verwendung von synchronisierten Methoden und Aussagen durch die Bereitstellung eines nicht-blockierenden Versuch zu erwerben eine Sperre (TryLock ()), ein Versuch, die Sperre zu erwerben , die unterbrochen werden kann (lockInterruptibly () und ein Versuch, acquire die Sperre, die eine Zeitüberschreitung verursachen kann (tryLock (long, TimeUnit)).
...