2009-08-07 13 views
6

Los futuros son muy convenientes, pero en la práctica, es posible que necesite algunas garantías para su ejecución. Por ejemplo, considere:¿Uso práctico de futuros? Es decir, ¿cómo matarlos?

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

La idea es iniciar algunas funciones de funcionamiento lento en paralelo. Pero no nos gustaría colgar para siempre si las funciones ejecutadas por los futuros no vuelven. Entonces usamos awaitAll() para poner un tiempo de espera en los futuros. Pero si ejecuta el código, verá que el temporizador de 5 segundos expira, pero el futuro de 10 segundos continúa ejecutándose y regresa más tarde. El tiempo de espera no mata el futuro; solo limita la espera de unirse.

Entonces, ¿cómo matar un futuro después de un período de tiempo de espera? Parece que los futuros no se pueden usar en la práctica a menos que esté seguro de que volverán en un período de tiempo conocido. De lo contrario, se corre el riesgo de perder subprocesos en el grupo de subprocesos hasta futuros no terminales hasta que no quede ninguno.

Así que las preguntas son: ¿cómo se matan los futuros? ¿Cuáles son los patrones de uso previstos para los futuros dados estos riesgos?

Respuesta

2

Los futuros están destinados a utilizarse en entornos en los que es necesario esperar a que se complete el cálculo, sin importar qué. Es por eso que se describen como utilizados para las funciones de ejecución lenta . Desea el resultado de esa función, pero tiene otras cosas que puede hacer mientras tanto. De hecho, puede tener muchos futuros, todos independientes entre sí, que desee ejecutar en paralelo, mientras espera hasta que todo esté completo.

El temporizador solo proporciona una espera para obtener resultados parciales.

+1

Pero dado que el problema de detención aún no se ha resuelto :), no tiene garantía de que una función regrese. Por lo tanto, es posible que los futuros nunca vuelvan. Entonces la pregunta original permanece ... Punto tomado sobre el awaitAll() que se usa para obtener resultados parciales. Entonces suena como un patrón de uso: pase una clase que guarda resultados parciales a medida que se generan, luego use el temporizador para sacarlos. – DrGary

1

Creo que el motivo por el que Future no se puede simplemente "matar" es exactamente el mismo que por qué java.lang.Thread.stop() es deprecated.

Mientras Future se está ejecutando, se requiere un subproceso. Para detener un futuro sin llamar a stop() en el subproceso que se ejecuta, se necesita una lógica específica de la aplicación: verificar una bandera específica de la aplicación o el estado interrumpido del subproceso que se ejecuta periódicamente es una forma de hacerlo.

Cuestiones relacionadas