Ein ReentrantLock ist im Gegensatz zu Konstrukten unstrukturiertsynchronized
- dh Sie müssen keine Blockstruktur zum Sperren verwenden und können sogar eine Methode zwischen Methoden sperren. Ein Beispiel:
private ReentrantLock lock;
public void foo() {
...
lock.lock();
...
}
public void bar() {
...
lock.unlock();
...
}
Ein solcher Fluss kann nicht über einen einzelnen Monitor in einem synchronized
Konstrukt dargestellt werden.
Abgesehen davon ReentrantLock
unterstützt Lock Poll Polling und unterbrechbare Lock Waits, die Timeout unterstützen . ReentrantLock
Unterstützt auch konfigurierbare Fairness- Richtlinien , die eine flexiblere Thread-Planung ermöglichen.
Der Konstruktor für diese Klasse akzeptiert einen optionalen Fairness- Parameter. Wenn die festgelegte Methode die Fairness-Einstellung nicht berücksichtigt. Es ist erfolgreich, wenn die Sperre verfügbar ist, auch wenn andere Threads warten.true
aktiviert ist, wird durch Sperren der Zugriff auf den am längsten wartenden Thread bevorzugt. Andernfalls garantiert dieses Schloss keine bestimmte Zugriffsreihenfolge. Programme mit fairen Sperren, auf die viele Threads zugreifen, weisen möglicherweise einen geringeren Gesamtdurchsatz auf (dh sind langsamer; oft viel langsamer) als Programme mit der Standardeinstellung, weisen jedoch zeitlich geringere Abweichungen auf, um Sperren zu erhalten und einen Mangel an Hunger zu gewährleisten. Beachten Sie jedoch, dass die Fairness der Sperren keine Fairness der Thread-Planung garantiert. Somit kann einer von vielen Threads, die eine faire Sperre verwenden, diese mehrmals hintereinander erhalten, während andere aktive Threads nicht fortschreiten und die Sperre derzeit nicht halten. Beachten Sie auch, dass die ohne ZeitangabetryLock
ReentrantLock
kann auch skalierbarer sein und bei höheren Konflikten eine viel bessere Leistung erbringen. Mehr dazu lesen Sie hier .
Diese Behauptung wurde jedoch bestritten; siehe folgenden Kommentar:
Beim Test der Wiedereintrittssperre wird jedes Mal eine neue Sperre erstellt, sodass keine ausschließliche Sperre erfolgt und die resultierenden Daten ungültig sind. Außerdem bietet der IBM Link keinen Quellcode für den zugrunde liegenden Benchmark, sodass nicht charakterisiert werden kann, ob der Test überhaupt korrekt durchgeführt wurde.
Wann sollten Sie ReentrantLock
s verwenden? Laut diesem DeveloperWorks-Artikel ...
Die Antwort ist ziemlich einfach: Verwenden Sie sie, wenn Sie tatsächlich etwas benötigen, synchronized
das nicht bereitgestellt wird, z. B. zeitgesteuerte Wartezeiten, unterbrechbare Wartezeiten, nicht blockstrukturierte Sperren, mehrere Bedingungsvariablen oder Sperrenabfragen. ReentrantLock
hat auch Skalierbarkeitsvorteile, und Sie sollten es verwenden, wenn Sie tatsächlich eine Situation haben, die hohe Konflikte aufweist. Denken Sie jedoch daran, dass die überwiegende Mehrheit der synchronized
Blöcke kaum Konflikte aufweist, geschweige denn hohe Konflikte. Ich würde empfehlen, mit Synchronisation zu entwickeln, bis sich die Synchronisation als unzureichend erwiesen hat, anstatt einfach davon auszugehen, dass "die Leistung besser ist", wenn Sie sie verwendenReentrantLock
. Denken Sie daran, dies sind erweiterte Tools für fortgeschrittene Benutzer. (Und wirklich fortgeschrittene Benutzer bevorzugen in der Regel die einfachsten Tools, die sie finden können, bis sie überzeugt sind, dass die einfachen Tools unzureichend sind.) Machen Sie es wie immer zuerst richtig und machen Sie sich dann Gedanken darüber, ob Sie es schneller machen müssen oder nicht.