Ablaufinvarianz bedeutet, dass Sperren auf einem Pro-Thread erworben werden und nicht pro-Aufruf-Basis.
Das ist eine irreführende Definition. Es ist wahr (so), aber es fehlt der wahre Punkt.
Reentrancy bedeutet (im Allgemeinen CS/IT Terminologie), dass Sie etwas tun, und während Sie es noch tun, tun Sie es noch einmal. Im Fall von Sperren bedeutet es, Sie so etwas wie diese auf einem einzigen Thread tut:
- Acquire eine Sperre auf „foo“.
- Etwas tun
- Erwerben Sie eine Sperre auf "foo". Beachten Sie, dass wir das zuvor erworbene Schloss nicht freigegeben haben.
- ...
- Entriegelungsschloss auf "foo"
- ...
- Entriegelungsschloss auf "foo"
Mit einem einspringenden Verriegelungs-/Schließmechanismus, der Versuch, das gleiche zu erwerben Die Sperre wird erfolgreich ausgeführt und erhöht einen internen Zähler, der zur Sperre gehört. Das Schloss wird nur freigegeben, wenn der aktuelle Schlosshalter es zweimal losgelassen hat.
Hier ist ein Beispiel in Java mit primitiven Objektsperren/Monitore ... die einspringende sind:
Object lock = new Object();
...
synchronized (lock) {
...
doSomething(lock, ...)
...
}
public void doSomething(Object lock, ...) {
synchronized (lock) {
...
}
}
Die Alternative zu Reentry ist nichtablaufinvarianten sichernd, wo es ein Fehler für einen Thread zu versuchen, wäre um ein Schloss zu erhalten, das es bereits hält.
Der Vorteil der Verwendung von Reentrant-Sperren besteht darin, dass Sie sich keine Gedanken über die Möglichkeit eines Ausfalls machen müssen, weil Sie versehentlich eine Sperre erhalten, die Sie bereits besitzen. Der Nachteil ist, dass Sie nicht davon ausgehen können, dass nichts, das Sie aufrufen, den Status der Variablen ändert, die die Sperre schützen soll. Dies ist jedoch normalerweise kein Problem.Sperren werden im Allgemeinen zum Schutz gegen gleichzeitige Zustandsänderungen verwendet, die von anderen Threads vorgenommen werden.
Also brauche ich nicht Deadlocks in Betracht ziehen?
Ja, Sie tun.
Ein Thread wird nicht gegen sich selbst blockieren (wenn das Schloss wieder einspringt). Sie können jedoch einen Deadlock erhalten, wenn andere Threads eine Sperre für das Objekt haben, das Sie sperren möchten.
Stellen Sie sich vor, ein Verfahren Sperren der Eingabe X-Objekt, und während sie in dieser Methode Sie rufen die gleichen Verfahren (entweder direkt oder über weitere in der Aufrufliste) und Sperrobjekt X wieder. Was geschieht?Wartest du auf die Sperre, die du bereits hältst, oder ist dir bewusst, dass der Thread, der es hält, auch der Thread ist, der es erneut aufruft und es passieren lässt? Dies wird Reentrancy genannt - Sie geben die gleiche Methode ein, mit der Sie bereits früher gearbeitet haben. – Patashu
Ja, synchronisierte Blöcke und Sperren in Java sind reentrant. Sobald der Thread foo über eine Sperrleiste verfügt, kann er sicher Methoden aufrufen, die ebenfalls Sperren sperren, ohne sie zuvor entsperren zu müssen. – Patashu
Sie müssen weiterhin Deadlock berücksichtigen, Deadlock kann auftreten, wenn zwei Threads aufeinander warten. – rubixibuc