ReentrantLock vs. synchronized
Vergleichen Sie die Funktionen von ReentrantLock (tryLock, lockInterruptibly, Fairness) mit dem Schlüsselwort synchronized.
ReentrantLock vs. synchronized ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Schlüsselwort synchronized
Das Java-Schlüsselwort synchronized stellt mithilfe der intrinsischen Sperre (Monitor) des Objekts den gegenseitigen Ausschluss sicher. Es ist einfach, aber eingeschränkt — ohne Timeout, Fairness oder Unterbrechbarkeit.
class Counter {
private int count = 0;
synchronized void increment() {
count++; // only one thread at a time
}
synchronized int get() { return count; }
}
Counter c = new Counter();
// Multiple threads can safely call increment()Grundlagen von ReentrantLock
ReentrantLock ist eine explizite Sperre aus java.util.concurrent.locks. Sie bietet denselben gegenseitigen Ausschluss wie synchronized, aber mit mehr Kontrolle. Die Sperre muss manuell in einem finally-Block freigegeben werden.
import java.util.concurrent.locks.*;
class SafeCounter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock(); // always release in finally!
}
}
int get() {
lock.lock();
try { return count; }
finally { lock.unlock(); }
}
}tryLock: Nicht blockierendes Erwerben
tryLock() versucht, die Sperre zu erwerben, ohne zu blockieren. Es gibt true zurück, wenn dies erfolgreich ist, und false, wenn die Sperre von einem anderen Thread gehalten wird.
ReentrantLock lock = new ReentrantLock();
if (lock.tryLock()) {
try {
System.out.println("Got the lock, doing work");
} finally {
lock.unlock();
}
} else {
System.out.println("Lock busy, skipping or retrying");
}tryLock mit Timeout
Warten Sie bis zu einer bestimmten Zeit, um die Sperre zu erwerben:
try {
if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
try {
// work with protected resource
System.out.println("Acquired within 500ms");
} finally {
lock.unlock();
}
} else {
System.out.println("Timed out waiting for lock");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}lockInterruptibly
lockInterruptibly() erwirbt die Sperre, sofern der Thread nicht unterbrochen wird — nützlich für abbrechbare Aufgaben, die auf eine Sperre warten:
try {
lock.lockInterruptibly(); // throws InterruptedException if interrupted
try {
// do work
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
System.out.println("Interrupted while waiting for lock");
Thread.currentThread().interrupt();
}Wiedereintrittsfähigkeit
Sowohl synchronized als auch ReentrantLock sind wiedereintrittsfähig — ein Thread, der die Sperre bereits hält, kann sie erneut erwerben, ohne einen Deadlock zu verursachen:
synchronized void outer() {
System.out.println("outer");
inner(); // same thread re-enters — OK
}
synchronized void inner() {
System.out.println("inner"); // same lock, same thread
}
// ReentrantLock:
ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.lock(); // acquire again — hold count = 2
lock.unlock(); // hold count = 1
lock.unlock(); // hold count = 0, lock releasedFairness-Richtlinie
Erstellen Sie eine faire ReentrantLock, um den Zugriff in FIFO-Reihenfolge zu gewähren — dies verhindert das Aushungern von Threads, verringert jedoch den Durchsatz:
// Unfair (default): no ordering guarantee, better throughput
ReentrantLock unfair = new ReentrantLock();
// Fair: threads acquire in arrival order
ReentrantLock fair = new ReentrantLock(true);
System.out.println(fair.isFair()); // trueCondition-Variablen
ReentrantLock stellt Condition-Objekte bereit — sie sind flexibler als wait()/notify():
ReentrantLock lock2 = new ReentrantLock();
Condition notEmpty = lock2.newCondition();
Queue<String> queue = new LinkedList<>();
// Producer
lock2.lock();
try {
queue.offer("item");
notEmpty.signal(); // wake one waiting thread
} finally { lock2.unlock(); }
// Consumer
lock2.lock();
try {
while (queue.isEmpty()) notEmpty.await(); // wait & release lock
System.out.println(queue.poll());
} finally { lock2.unlock(); }Wann Sie ReentrantLock statt synchronized verwenden sollten
Verwenden Sie synchronized, wenn:
- ein einfacher gegenseitiger Ausschluss benötigt wird
- kein Timeout, keine Fairness und keine Unterbrechbarkeit erforderlich sind
Verwenden Sie ReentrantLock, wenn:
- tryLock() oder tryLock(timeout) benötigt wird
- lockInterruptibly() benötigt wird
- eine faire Reihenfolge erforderlich ist
- mehrere Condition-Variablen benötigt werden
Sperrenanzahl und Überwachung
ReentrantLock stellt Diagnosemethoden bereit:
ReentrantLock lock3 = new ReentrantLock();
lock3.lock();
lock3.lock(); // reentrant — hold count 2
System.out.println(lock3.getHoldCount()); // 2
System.out.println(lock3.isHeldByCurrentThread()); // true
System.out.println(lock3.isLocked()); // true
System.out.println(lock3.getQueueLength()); // 0 (no waiting threads)
lock3.unlock();
lock3.unlock(); // fully releasedHäufiger Fehler: Entsperren ohne Sperre
Der Aufruf von unlock(), wenn der aktuelle Thread die Sperre nicht hält, löst IllegalMonitorStateException aus. Kombinieren Sie lock und unlock immer paarweise oder verwenden Sie try-finally:
ReentrantLock lock4 = new ReentrantLock();
try {
// If lock() is never called (e.g., skipped by exception before this line)
lock4.unlock(); // throws IllegalMonitorStateException
} catch (IllegalMonitorStateException e) {
System.out.println("Must lock before unlock!");
}Kurzer Test
Welche Methode von ReentrantLock ermöglicht es einem Thread, die Sperre zu erwerben oder sofort zurückzukehren, ohne zu blockieren, wenn die Sperre nicht verfügbar ist?
Zusammenfassung: ReentrantLock vs synchronized
Wichtige Erkenntnisse:
- Beide stellen gegenseitigen Ausschluss und Wiedereintrittsfähigkeit bereit
- ReentrantLock bietet zusätzlich: tryLock, lockInterruptibly, Fairness und Condition-Objekte
- Geben Sie die Sperre immer im finally-Block frei
- synchronized ist einfacher — bevorzugen Sie es, wenn seine Funktionen ausreichen
- ReentrantLock für fortgeschrittene Szenarien: Timeouts, Unterbrechbarkeit und mehrere Conditions
Häufig gestellte Fragen
Ist die Lektion „ReentrantLock vs. synchronized“ kostenlos?
Ja — der vollständige Text von „ReentrantLock vs. synchronized“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „ReentrantLock vs. synchronized“?
Vergleichen Sie die Funktionen von ReentrantLock (tryLock, lockInterruptibly, Fairness) mit dem Schlüsselwort synchronized. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „ReentrantLock vs. synchronized“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- ReentrantLock vs. synchronized
- ReadWriteLock für Leser-Schreiber-Szenarien
- Atomare Variablen: Aktualisierungen ohne Locks
- StampedLock und optimistische Lesezugriffe