Gibt es ein Mutex-Objekt in Java oder eine Möglichkeit, eines zu erstellen? Ich frage, weil ein Semaphor-Objekt, das mit 1 Erlaubnis initialisiert wurde, mir nicht hilft. Denken Sie an diesen Fall:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
Wenn beim ersten Erwerb eine Ausnahme auftritt, erhöht die Freigabe im catch-Block die Berechtigungen, und das Semaphor ist kein binäres Semaphor mehr.
Wird der richtige Weg sein?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
Wird der obige Code sicherstellen, dass das Semaphor binär ist?
Antworten:
Siehe diese Seite: http://www.oracle.com/technetwork/articles/javase/index-140767.html
Es hat ein etwas anderes Muster, das (glaube ich) das ist, wonach Sie suchen:
In dieser Verwendung rufen Sie erst
release()
nach einem erfolgreichen anacquire()
quelle
Jedes Objekt in Java kann mithilfe eines
synchronized
Blocks als Sperre verwendet werden . Dadurch wird auch automatisch die Sperre aufgehoben, wenn eine Ausnahme auftritt.Weitere Informationen hierzu finden Sie hier: Eigensperren und Synchronisierung
quelle
synchronized
Sie werden sehen, was besser lesbar und weniger fehleranfällig ist.transaction.begin(); transaction.commit()
. B. ) aufzuheben .someObject.wait(timeout)
undsomeObject.notify()
während Sie den Code dieser Antwort suchen.quelle
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
, von: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/… ... obwohl Sie einen Punkt haben. Argvs Antwort illustriert oder erklärt diese Operationen nicht.private final ReentrantLock _mutex = ...
, können Sie getHoldCount () verwenden , um die Anzahl der erneuten Thread-Sperren zurückzugeben. (Sie können ein anwendenCondition
, um dies zu verhindern. Siehe die API .)Niemand hat dies klar erwähnt, aber diese Art von Muster ist normalerweise nicht für Semaphoren geeignet. Der Grund dafür ist , dass jeder Thread eine Semaphore freigeben kann, aber Sie wollen in der Regel nur den Besitzer Thread , der ursprünglich zu entsperren können gesperrt werden . Für diesen Anwendungsfall verwenden wir in Java normalerweise ReentrantLocks, die wie folgt erstellt werden können:
Und das übliche Design-Verwendungsmuster ist:
Hier ist ein Beispiel im Java-Quellcode, in dem Sie dieses Muster in Aktion sehen können.
Wiedereintrittsschlösser haben den zusätzlichen Vorteil, dass sie die Fairness unterstützen.
Verwenden Sie Semaphoren nur, wenn Sie eine Semantik ohne Eigentumsfreigabe benötigen.
quelle
count=1
ist keine gegenseitige Ausschlusssperre.lock
zBReentrantLock
einmutex
? Ich bin mir nicht sicher, warummutex
und werdebinary semaphore
als dieselbe Einheit angesehen.Semaphore
kann von jedem Thread freigegeben werden, so dass möglicherweise kein Schutz garantiert wirdcritical section
. Irgendwelche Gedanken?Ich denke, Sie sollten versuchen mit:
Während der Semaphor-Initialisierung:
Und in deinem
Runnable Implementation
quelle
Ein Fehler im ursprünglichen Beitrag ist der Aufruf von purchase (), der in der try-Schleife festgelegt wurde. Hier ist ein korrekter Ansatz zur Verwendung des "binären" Semaphors (Mutex):
quelle
Um sicherzustellen, dass a
Semaphore
binär ist, müssen Sie beim Erstellen des Semaphors nur sicherstellen, dass Sie die Anzahl der Genehmigungen als 1 übergeben. Die Javadocs haben etwas mehr Erklärung.quelle
Die Sperre jedes Objekts unterscheidet sich kaum vom Mutex / Semaphore-Design. Zum Beispiel gibt es keine Möglichkeit, das Durchlaufen verknüpfter Knoten korrekt zu implementieren, indem die Sperre des vorherigen Knotens aufgehoben und der nächste erfasst wird. Mit Mutex ist es jedoch einfach zu implementieren:
Derzeit gibt es keine solche Klasse
java.util.concurrent
, aber die Mutext-Implementierung finden Sie hier Mutex.java . In Bezug auf Standardbibliotheken bietet Semaphore all diese Funktionen und vieles mehr.quelle