2017-03-27 2 views
3
val future = Future { 
    println("hello") 
    Thread.sleep(2000) 
} 

future.onComplete(_ => println("done")) 

Der Code in der Zukunft oben blockiert.Blockiert Scala Future [T] intern? Was passiert in Scala Future?

Meine Frage ist: seit Future verwendet eine ExecutionContext. Bedeutet es, dass ein Thread in diesem Thread-Pool während der Ausführung des darin enthaltenen Codes durch diese Zukunft blockiert wird?

Welcher Thread wird genau den Rückruf aufrufen? Ein weiterer Thread aus dem Thread-Pool? Wie wird es herausfinden, dass der in dieser Zukunft ausgeführte Code beendet ist?

+0

Sie könnten die ID des Threads innerhalb der Zukunft überprüfen, um zu sehen, welche Threads es ist. – Carcigenicate

Antwort

2

Angenommen Sie anrufen Code, der Blöcke in einem Future:

seit Zukunft ExecutionContext verwendet. Bedeutet es, dass ein Thread in diesem Thread-Pool während der Ausführung des darin enthaltenen Codes durch diese Zukunft blockiert wird?

Im Wesentlichen ja. Wenn Sie den Sperrcode aufrufen, muss etwas blockiert werden. Ein ExecutionContext ist jedoch allgemeiner als ein Thread-Pool. Es kann Thread-Pool sein, aber es kann auch etwas sein, das Anrufe auf andere Weise verwaltet. Trotzdem wird etwas blockiert, meistens wird es ein roter Faden sein. scala.concurrent.ExecutionContext.Implicits.global ist beispielsweise ein ForkJoinPool.

Welcher Thread wird genau den Rückruf aufrufen?

Das ist meist bis zu der ExecutionContext zu entscheiden. Sie können Thread.currentThread in Ihrem Rückrufcode drucken, aber es gibt keinen Grund (außer vielleicht Debugging), warum Sie diese Informationen wirklich wissen müssen. Dein Code sollte das sicher nicht wissen müssen. In der Regel bedeutet dies den nächsten verfügbaren Thread im Pool, bei dem es sich um den gleichen Thread handeln könnte, der den Körper des Future oder einen anderen Thread ausgeführt hat. Es scheint, dass derselbe Thread, der das Original Future ausführt, die Rückrufe absetzt, aber nur für die Ausführung plant.

Wie wird es herausfinden, dass die Codeausführung in dieser Zukunft abgeschlossen ist?

onComplete Aufruf wird entweder sofort ausgeführt werden, wenn der Basiswert Promise der Future im fertigen Zustand ist, oder ein CallbackRunnable wird auf eine Liste von Hörern hinzugefügt werden, ausgeführt werden, wenn das Versprechen abgeschlossen ist. DefaultPromise#tryComplete ruft die Listener unmittelbar nach der Ausführung der Berechnung auf. Siehe this excerpt des aktuellen Codes.

+0

Vielen Dank für eine ausgezeichnete Antwort. Ich habe noch eine Frage. Da Futures auf Threads basieren und intern einen Thread blockieren, sind sie nicht ereignisgesteuert. Es gibt keine Sache wie eine gerade Schleife, die Ereignis für Ereignis ausgeführt wird. Warum sagen wir, dass Futures "ereignisgesteuert" sind? (Ich fand das in "Simultane Programmierung in Scala lernen" von Aleksandar Prokopec) – tomdavies

+1

@tomdavies Da Sie die Ereignisschleife in Node.js blockieren können, bedeutet das, dass Node.js nicht ereignisgesteuert ist. (d. h. wer kam zu der Behauptung, dass etwas nicht ereignisgesteuert ist, gibt es die Möglichkeit zu blockieren?) –

+0

@ViktorKlang Tut mir leid, das scheint eine Neulingsfrage zu sein, aber ich habe kürzlich viel darüber gelesen und ich habe die endgültige Antwort nicht gefunden. Vielleicht sollte ich meine Frage umformulieren: Scala-Futures basieren auf Thread-Pools (mehr oder weniger standardmäßig), während Node.js auf Event-Loop-Ausführungsereignissen basiert. Was macht also Futures in Scala ereignisgesteuert? Ist es die Tatsache, dass die angehängten Callbacks ausgeführt werden, wenn sie abgeschlossen sind? – tomdavies

Verwandte Themen