2013-05-27 13 views
5

Verwendet Sperren (java.util.concurrent.locks.Lock) anstelle von Schlüsselwort synchronized + Methode wait() und Methode völlig gleich?Explizite Sperren vs implizite Sperren

Kann ich Thread-sicher mit Sperren (explizite Sperren) anstelle von impliziten Sperren (synchronized) programmieren?

Wie ich weiß, habe ich immer implizite Sperren verwendet. Ich bin mir der Vorteile der Lock Schnittstellen-Implementierung wie Methoden bewusst: isLocked(), getLockQueueLength(), getHoldCount(), etc ... aber noch die alte Schule Weg (wait() und notify()) hätte andere Grenzen als diese Methoden nicht?

Ich bin mir auch der Möglichkeit bewusst, eine Sperre mit einem (boolean fairness) Parameter zu konstruieren, der Mangel an Hunger ermöglicht.

+1

Nun, es ist nicht * total * das gleiche, als wären sie zu 100% identisch, dann wäre die Existenz eines überflüssig ;-) –

+1

@Joachim Sauer Sicherlich wäre es nicht das erste Mal, dass eine Programmiersprache zwei identische hätte Möglichkeiten, das Gleiche zu tun. – Patashu

+1

@Patashu: sicherlich nicht. Aber es ist unwahrscheinlich, dass sie eine zweite Option so lange nach der ersten hinzufügen, wenn es nicht zumindest einige Vorteile gibt (wie die 'isLocked()' Methode, ...). –

Antwort

7

Ja, absolut können Sie thread-sichere Programm schreiben mit java.util.concurrent.locks.Lock. Wenn Sie eine Implementierung von java.util.concurrent.locks.Lock wie ReentrantLock interne Implementierung sehen, verwendet alte synchronized Blöcke.

Sperrimplementierungen bieten umfangreichere Sperroperationen, als mit synchronisierten Methoden und Anweisungen erzielt werden können. Sie ermöglichen eine flexiblere Strukturierung, haben möglicherweise ganz andere Eigenschaften und können mehrere zugehörige Bedingungsobjekte unterstützen.

Hinzufügen zu meinem Unterschied das synchronized Schlüsselwort hat natürlich Sprachunterstützung eingebaut. Dies kann bedeuten, dass der JIT synchronised blocks auf eine Weise optimieren kann, die mit Locks nicht möglich ist. z.B. es kann synchronized blocks kombinieren. synchronisiert ist am besten für eine kleine Anzahl von Threads, die auf eine Sperre zugreifen, und Lock ist möglicherweise am besten für eine hohe Anzahl von Threads, die auf dieselben Sperren zugreifen. Auch synchronized Block macht keine Garantien über die Reihenfolge, in der Threads warten auf die Eingabe Zugriff gewährt werden.

2

Sperren und synchronized Blöcke haben die gleiche Semantik und bieten die gleichen Garantien aus einer Java Memory Model Perspektive. Der Hauptunterschied besteht darin, dass Sperren mehr Kontrolle bieten (z. B. mit tryLock oder wenn eine Sperre verlangt wird, um fair zu sein usw.), die eine flexiblere und feinkörnigere Sperrverwaltung ermöglichen.

Wenn Sie jedoch diese zusätzlichen Funktionen nicht benötigen, ist es besser, einen einfachen alten synchronized Block zu verwenden, da es den Raum für Fehler reduziert (z. B. können Sie nicht zu unlock es "vergessen").