Welche Implementierungen von Condition benötigen keinen aktuellen Thread, um die Sperre zu halten?

8

Kürzlich las ich einige Beispiele aus dem Kapitel 8 der Art der Multiprozessor-Programmierung , über " Monitore und Blockierungssynchronisation ", die das signalAll() eines Condition -Objekts verwenden, ohne dass die mit diesem Condition verknüpfte Sperre übernommen wird.

Überraschenderweise fand ich keine Korrektur für diese Beispiele in den Buch-Errata . Außerdem schlagen sie eine Korrektur für das Beispiel in Abbildung 8.12 von FifoReadWriteLock vor, aber sie verwenden weiterhin signalAll() , ohne dass die Sperre gehalten wird. Das hat mich gestört und ich habe versucht, andere Überlegungen zu diesen Beispielen anzustellen, um die Gründe zu verstehen, warum diese Java-Beispiele auf diese Weise geschrieben wurden.

Zum Beispiel die Antwort auf die Frage "Wie funktioniert ein Read-Write-Mutex / Lock? "zeigt das gleiche Beispiel für die Implementierung von FifoReadWriteLock , das writeUnlock() als implementiert:

%Vor%

Über das Fehlen der Lock-Erfassung können Sie zwei verschiedene Gründe lesen:

  1. benutze es nur als Pseudocode
  2. einige Implementierung einer Bedingung Variable erfordert nicht, dass die Sperre gehalten wird, um zu signalisieren.

Es ist schwierig, das erste Argument zu akzeptieren, da das Buch Beispiele in Java verwendet und ausdrücklich sagt:

  

Das Buch verwendet die Java-Programmiersprache.

Über den zweiten Punkt weiß ich, dass die Java-API in java.util.concurrent.locks.Condition für signal() Methode:

  

Eine Implementierung kann (und normalerweise) erfordert, dass der aktuelle Thread die mit diesem Condition verknüpfte Sperre bei Aufruf dieser Methode enthält.

Wenn " eine Implementierung nur " ist, bedeutet dies, dass dies NICHT zwingend erforderlich ist. Nach meinem besten Wissen finde ich keine Implementierung, die diese Anforderung NICHT erfüllt. Also würde ich gerne wissen, welche Implementierungen von Java Condition keinen aktuellen Thread benötigen, um die Sperre zu halten?

    
Miguel Gamboa 06.04.2016, 11:04
quelle

1 Antwort

1

Mir ist keine Condition -Implementierung im JDK bekannt, die Warten oder Signalisieren erlaubt, ohne gleichzeitig den Monitor zu besitzen.

Praktisch alle java.util.concurrent -Klassen verlassen sich auf AbstractQueuedSynchronizer , was den gleichen Vertrag wie die eingebauten Überwachungsmethoden wait() / notify() / notifyAll() für die von ihr bereitgestellten Bedingungsvariablen festlegt, dh Besitz erfordert die interne Sperre, um den Aufruf von await() / signal() / signalAll() .

zu ermöglichen

Wenn Sie ein einfaches Beispiel mit dem vorgeschlagenen FifoReadWriteLock versuchen, werden Sie feststellen, dass es eine große Menge von IllegalMonitorStateExceptions mit seiner Methode writeUnlock() ausgibt. Diese Ausnahmen verschwinden, wenn Sie den Lock-try-finally-Ansatz von den anderen Methoden anwenden.

Während der Besitz des Monitors in der Tat nicht unbedingt erforderlich ist, zu warten oder zu signalisieren, ist es oft der bevorzugte Ansatz, da er Sie vor raschen Zustandslesungen bewahrt, sollte er nicht zu kostspielig sein wie die Übergabe zwischen den internen Wartezeiten Derselbe Monitor kann immer noch ziemlich effizient ausgeführt werden, und weil Sie ihn meistens sowohl für die Signalisierung als auch für die Planung benötigen, anstatt nur zu signalisieren.

    
Dimitar Dimitrov 18.04.2016, 23:26
quelle