2009-08-07 6 views
6

Futures sind sehr praktisch, aber in der Praxis benötigen Sie möglicherweise einige Garantien für ihre Ausführung. Betrachten wir zum Beispiel:Praktische Verwendung von Futures? Ie, wie man sie tötet?

import scala.actors.Futures._ 

def slowFn(time:Int) = { 
    Thread.sleep(time * 1000) 
    println("%d second fn done".format(time)) 
} 

val fs = List(future(slowFn(2)), future(slowFn(10))) 
awaitAll(5000, fs:_*) 
println("5 second expiration. Continuing.") 

Thread.sleep(12000)  // ie more calculations 
println("done with everything") 

Die Idee, einige langsam laufenden Funktionen parallel zum Auftakt ist. Aber wir möchten nicht für immer hängen bleiben, wenn die von den Futures ausgeführten Funktionen nicht zurückkehren. Wir verwenden also "gawarAll()", um eine Auszeit für die Futures zu setzen. Aber wenn Sie den Code ausführen, sehen Sie, dass der 5-Sekunden-Timer abläuft, aber die 10-Sekunden-Zukunft läuft weiter und kehrt später zurück. Die Zeitüberschreitung tötet die Zukunft nicht ab; Es beschränkt nur die Join-Wartezeit.

Wie tötet man eine Zukunft nach einer Zeitüberschreitung? Es scheint, dass Futures nicht in der Praxis verwendet werden können, es sei denn, Sie sind sicher, dass sie in einer bekannten Zeit zurückkehren werden. Andernfalls laufen Sie Gefahr, Threads im Thread-Pool an nicht terminierende Futures zu verlieren, bis keine übrig sind.

Also sind die Fragen: Wie tötet man Futures? Was sind die beabsichtigten Nutzungsmuster für Futures angesichts dieser Risiken?

Antwort

2

Futures sind für Einstellungen vorgesehen, bei denen Sie auf die Ausführung der Berechnung warten müssen, egal was passiert. Deshalb werden sie als langsamlaufend beschrieben Funktionen. Sie wollen das Ergebnis dieser Funktion, aber Sie haben andere Dinge, die Sie in der Zwischenzeit tun können. Tatsächlich könnten Sie viele voneinander unabhängige Futures haben, die Sie parallel ausführen möchten, während Sie warten, bis alles abgeschlossen ist.

Der Timer bietet nur eine Wartezeit, um Teilergebnisse zu erhalten.

+1

Da aber das Halteproblem noch nicht gelöst wurde :), haben Sie keine Garantie, dass eine Funktion zurückkehrt. Daher können Futures niemals zurückkehren. So bleibt die ursprüngliche Frage ... Punkt, der über das appointAll() genommen wird, um Teilergebnisse zu ziehen. Das klingt wie ein Nutzungsmuster: Übergeben Sie eine Klasse, die Teilergebnisse speichert, wenn sie generiert werden, und verwenden Sie den Timer, um sie herauszuziehen. – DrGary

1

Ich denke, der Grund, warum Future nicht einfach "getötet" werden kann, ist genau das gleiche wie warum java.lang.Thread.stop() deprecated ist.

Während Future ausgeführt wird, ist ein Thread erforderlich. Um eine Zukunft zu stoppen, ohne stop() auf dem ausführenden Thread aufzurufen, wird anwendungsspezifische Logik benötigt: das regelmäßige Überprüfen auf ein anwendungsspezifisches Flag oder den unterbrochenen Status des ausführenden Threads ist eine Möglichkeit.

Verwandte Themen