ReadWriteLock
downgrade ist erlaubt von ReentrantReadWriteLock
implementation ( tryLock()
aus dem Beispiel unten gibt immer true
zurück):
Was war die Idee dahinter, ein Lock-Upgrade auf ähnliche Weise nicht zuzulassen? Die tryLock()
-Methode für eine Write -Sperre unten könnte true
ohne Risiko für einen Deadlock zurückgeben, wenn keine anderen Threads vorhanden sind, die eine Read -Sperre halten:
Zunächst möchten wir darauf hinweisen, dass Upgrade und Downgrade in Bezug auf die semantische Komplexität für ReadWriteLock
s nicht äquivalent sind.
Sie müssen keine Konflikte abwehren, um eine Downgrade-Transaktion abzuschließen, da Sie bereits die meisten Eskalationsberechtigungen für die Sperre besitzen und weil Sie garantiert der einzige Thread sind, der derzeit ein Downgrade durchführt. Dasselbe gilt nicht für das Upgrade, daher muss der Mechanismus, der das Upgrade unterstützt, natürlich komplexer (oder viel intelligenter) sein.
Um verwendbar zu sein, muss der Upgrade-Mechanismus Deadlocks verhindern, falls zwei Lese-Threads gleichzeitig versuchen, ein Upgrade durchzuführen (oder speziell für ReentrantReadWriteLock
, falls ein einzelner Lese-Thread mit mehreren Lese-Sperren versucht, ein Upgrade durchzuführen). Darüber hinaus muss der Mechanismus angeben, wie die fehlgeschlagene Aktualisierungsanforderung gehandhabt werden soll (wird ihre Lesesperre ungültig gemacht) und das ist noch weniger trivial.
Wie Sie wahrscheinlich schon sehen, ist das vollständige Behandeln dieser Probleme in ReentrantReadWriteLock
unbequem, (noch, das ist es, was .NET %Co_de% versucht und ich denke tatsächlich gelingt es). Meine Vermutung ist, dass, während ReaderWriterLock
in einigen trivialen Fällen erfolgreich sein könnte, die Upgrade-Fähigkeit für den normalen Gebrauch noch nicht gut genug wäre - unter schwer genug Konkurrenz, wenn Sie das Rennen um die Schreibsperre verlieren, sind Sie im selben Boot, als ob du die Lesesperre entsperrt hättest und versucht hast, die Schreibsperre zu erhalten (was die Möglichkeit für jemanden anderen übrig lässt, hineinzuschleichen und die Schreibsperre dazwischen zu nehmen).
Eine gute Möglichkeit, die Aktualisierbarkeit von Sperren zu ermöglichen, besteht darin, dass nur ein einzelner Thread versucht, ein Upgrade durchzuführen - das ist final boolean writeLockAcquired = readWriteLock.writeLock().tryLock();
tut oder was .NET ReentrantReadWriteUpdateLock
tun. Ich würde jedoch immer noch empfehlen% 8_%% von Java 8 als:
Tags und Links java concurrency reentrantlock reentrantreadwritelock