ich nicht scheinen, um herauszufinden, warum die folgenden Code Deadlocks:Deadlock mit synchronisierten und scala Futures
"Locks around blocking futures" should "be re-entrant" in {
val lock = new Object()
def processInFuture = {
lock.synchronized {
// simulate async call made blocking
Await.result(Future {
blocking {
logger.info("Sleeping")
Thread.sleep(100)
logger.info("Waking")
}
}, Duration.Inf)
}
}
// fire off 10 async events and wait on each one
(0 until 10).
map(_ => Future { processInFuture }).
foreach(future => Await.result(future, Duration.Inf))
}
Ich kann nicht sehen, warum ein asynchrones in sync in einem kritischen Abschnitt macht die ganze Gabel- verursacht schließe dich dem Pool an.
Wenn ich die Zukunft in einem separaten Pool aus dem Fork Join Pool ausführen, funktioniert es. Ich verstehe nicht, warum der Fork-Join-Pool-Thread die anderen Threads nicht blockiert und dann erst beendet? Liegt es daran, dass der Pool irgendwie blockiert ist?
Ich weiß, es ist immer am besten, alles zu machen async, wenn seine async, aber einige Szenarien für das nicht zulassen (zum Beispiel Cache-Population mit einer Guave-Cache)
- EDIT
Zur Veranschaulichung @ Dimas Antwort das funktioniert
"Locks around blocking futures" should "be re-entrant" in {
val lock = new Object()
def processInFuture = {
blocking {
lock.synchronized {
// simulate async call made blocking
Await.result(Future {
blocking {
logger.info("Sleeping")
Thread.sleep(100)
logger.info("Waking")
}
}, Duration.Inf)
}
}
}
// fire off 10 async events and wait on each one
(0 until 10).
map(_ => Future { processInFuture }).
foreach(future => Await.result(future, Duration.Inf))
}
Wenn dies ein gängiges Muster ist, ist der Code, den Sie geschrieben haben, falsch. Mit welchem Protokollierungsrahmen arbeiten Sie? – Falmarri
Abgesehen von der Frage, warum dieses Beispiel blockiert, sollten Sie vielleicht erklären, was Sie wirklich tun möchten, da dieses Beispiel im Allgemeinen als pathologisch betrachtet wird. Es gibt Lösungen, die existieren (z. B. akka), die viel besser geeignet sind, den gemeinsamen veränderbaren Zustand zu schützen, während mit asynchronen Konstrukten wie Futures gearbeitet wird. Ich kann mir eigentlich keinen vernünftigen Grund vorstellen, Locks mit Futures zu mischen, es sei denn, das Schloss war in Code, auf den Sie keinen Zugriff hatten. –
Ich stieß auf ein Szenario, in dem ein Client, den ich nicht besitze, dies grundsätzlich tut und ich diesen synchronen Aufruf von anderen Async-Aufrufen als Teil eines trägen Caches schützen muss.Ich hätte es als sicher angenommen, einen asynchronen Anruf in einen Synchronisierungsanruf zu machen und ihn so in einem kritischen Abschnitt zu behandeln, ob das eine gute Idee ist oder nicht – devshorts