Anwendungsfall von scala.concurrent.blocking

72

Ich bin auf die scala.concurrent.blockingMethode gestoßen, und laut der Scala-Dokumentation ist dies ...

Wird verwendet, um einen Code zu kennzeichnen, der möglicherweise blockiert, sodass der aktuelle BlockContext das Verhalten der Laufzeit anpassen kann. Das ordnungsgemäße Markieren des Blockierungscodes kann die Leistung verbessern oder Deadlocks vermeiden.

Ich habe Zweifel:

  • Was ist der Faktor, mit dem neue Threads erzeugt werden?
  • Gilt dies nur für den scala.concurrent.ExecutionContext.Implicits.globalAusführungskontext oder auch für vom Benutzer erstellte Ausführungskontexte?
  • Was passiert, wenn ich eine ausführbare Datei mit blocking {... umschließe }?
  • Jeder praktische Anwendungsfall, in dem wir dieses Konstrukt verwenden sollten.
Sourav Chandra
quelle

Antworten:

59
  1. Die neuen Threads werden im Fork / Join-Pool erzeugt, wenn festgestellt wird, dass alle Threads im Fork / Join-Pool mithilfe des joinKonstrukts aufeinander warten , und es sind weitere Arbeiten zu erledigen, die möglicherweise einen der Threads beenden könnten. Wenn einer der ForkJoinWorkerThreads Code ausführt, der andere als die Verwendung blockiert join, kann er den Pool alternativ mit ManagedBlockers benachrichtigen .
  2. Es ist möglicherweise auf jede Art von Ausführungskontexten anwendbar. Es dient als Benachrichtigung für die ExecutionContextImplementierung, dass der von einem Arbeitsthread ausgeführte Code unter bestimmten Bedingungen möglicherweise blockiert und dass diese Bedingung möglicherweise durch Berechnen eines anderen unter Verwendung eines anderen Threads behoben wird . Der Ausführungskontext kann darauf reagieren oder nicht. In der aktuellen Implementierung (2.10, 2.11) blockingfunktioniert dies nur mit dem globalen Standardausführungskontext.
  3. Wenn Sie eine ausführbare Datei mit Blockierung umschließen, entsteht ein gewisser Laufzeitaufwand. Tun Sie dies also nicht immer.
  4. Wenn Sie eine Berechnung haben, die lange dauert, z. B. Sekunden oder Minuten, oder wenn Sie darauf warten, dass eine Zukunft abgeschlossen wird Await, oder wenn Sie darauf warten, dass der Zustand eines Monitors behoben wird, und dieser Zustand durch eine andere Aufgabe behoben werden kann / Zukunft, die im selben Ausführungskontext ausgeführt werden sollte - in all diesen Fällen sollten Sie verwenden blocking.

BEARBEITEN:

Schauen Sie sich Kapitel 4 im Buch Learning Concurrent Programming in Scala an .

axel22
quelle
2
Was gewinnen wir durch die Verwendung blocking? Sollte dies nur mit Futures verwendet werden (nicht im Haupt-Thread)?
macht
Sie können es überall verwenden, aber es wirkt sich nur auf die Arbeitsthreads aus, dh auf Berechnungen, mit denen ausgeführt wird Future { ... }.
Axel22
Hier bereits eine Antwort gefunden stackoverflow.com/questions/13097754/…
maks
1
Es scheint ein allgemeines Interesse an Codebeispielen für bewährte Verfahren zu bestehen.
Mike Slinn
2
@Suma Ich stimme zu, dass eine lang laufende Berechnung nicht unter die Definition von axel22 passt, insbesondere Punkt 2. Lang laufende Rechenwürfel profitieren nicht von der Arbeit, die in anderen Threads berechnet wurde, sondern es werden weniger Ressourcen benötigt, um abgeschlossen zu werden. Ich bin gerade auf eine Situation gestoßen, in der wir akka EC (ForkJoin) mit Blocking {} verwendet haben und keine Threads mehr haben, weil 2k dieser langen Berechnungen nicht rechtzeitig abgeschlossen wurden. Ich würde gerne eine Begründung hören, wie das Blockieren von {} langjährigen unabhängigen Berechnungen zugute kommt.
Tim