2009-08-07 7 views
6

Les contrats à terme sont très pratiques, mais en pratique, vous aurez peut-être besoin de garanties quant à leur exécution. Par exemple, considérons:Utilisation pratique des contrats à terme? C'est à dire, comment les tuer?

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") 

L'idée est de lancer certaines fonctions de fonctionnement lent en parallèle. Mais nous ne voudrions pas rester éternellement si les fonctions exécutées par les futurs ne reviennent pas. Nous utilisons donc awaitAll() pour mettre un timeout sur les futures. Mais si vous exécutez le code, vous voyez que le délai de 5 secondes expire, mais le futur de 10 secondes continue de s'exécuter et revient plus tard. Le timeout ne tue pas le futur. cela limite simplement l'attente de la jointure.

Alors, comment tuer un avenir après une période de timeout? Il semble que les contrats à terme ne peuvent pas être utilisés dans la pratique, à moins que vous ne soyez certain qu'ils reviendront dans un laps de temps connu. Sinon, vous risquez de perdre des threads dans le pool de threads pour des contrats à terme sans fin jusqu'à ce qu'il n'en reste plus. Donc, les questions sont: Comment tuer les futurs? Quels sont les modèles d'utilisation prévus pour les contrats à terme étant donné ces risques?

Répondre

2

Les contrats à terme sont destinés à être utilisés dans des environnements où vous devez attendre que le calcul soit terminé, quoi qu'il arrive. C'est pourquoi ils sont décrits comme étant utilisés pour les fonctions lentes. Vous voulez le résultat de cette fonction, mais vous avez d'autres choses que vous pouvez faire en attendant. En fait, vous pourriez avoir de nombreux futurs, tous indépendants les uns des autres, que vous voudrez peut-être exécuter en parallèle, pendant que vous attendez que tout soit terminé.

Le temporisateur fournit simplement une attente pour obtenir des résultats partiels.

+1

Mais puisque le problème d'arrêt n'a pas encore été résolu :), vous n'avez aucune garantie qu'une fonction reviendra. Ainsi, les contrats à terme peuvent ne jamais revenir. Donc la question originale reste ... Point pris à propos de l'utilisation de awaitAll() pour obtenir des résultats partiels. Cela ressemble à un modèle d'utilisation: passez dans une classe qui enregistre des résultats partiels à mesure qu'ils sont générés, puis utilisez la minuterie pour les extraire. – DrGary

1

Je pense que la raison pour laquelle Future ne peut pas simplement être "tué" est exactement la même que pour la raison pour laquelle java.lang.Thread.stop() est deprecated.

Lorsque Future est en cours d'exécution, un thread est requis. Afin d'arrêter un avenir sans appeler stop() sur le thread en cours d'exécution, une logique spécifique à l'application est nécessaire: vérifier un indicateur spécifique à l'application ou l'état interrompu du thread en cours d'exécution est une façon de le faire.

Questions connexes