2009-08-07 16 views
6

I futures sono molto convenienti, ma in pratica, potresti aver bisogno di alcune garanzie sulla loro esecuzione. Ad esempio, prendere in considerazione:Uso pratico dei futures? Cioè, come ucciderli?

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'idea è quella di avviare alcune funzioni di rallentamento in parallelo. Ma non vorremmo restare in eterno se le funzioni eseguite dal futuro non tornano. Quindi usiamo awaitAll() per mettere un timeout sul futuro. Ma se si esegue il codice, si vede che il timer 5 secondi scade, ma il futuro 10 secondi continua a funzionare e restituisce in seguito. Il timeout non uccide il futuro; limita solo l'attesa di join.

Quindi, come uccidi un futuro dopo un periodo di sospensione? Sembra che i futures non possano essere utilizzati nella pratica a meno che tu non sia certo che torneranno in un lasso di tempo noto. In caso contrario, si corre il rischio di perdere thread nel pool di thread per i future senza scadenza finché non ne rimane nessuno.

Quindi le domande sono: come si uccide il futuro? Quali sono i modelli di utilizzo previsti per i futures dati questi rischi?

risposta

2

I futures devono essere utilizzati nelle impostazioni in cui è necessario attendere il completamento del calcolo, a prescindere da cosa. Ecco perché sono descritti come utilizzati per le funzioni a esecuzione ridotta. Vuoi il risultato di quella funzione, ma nel frattempo hai altre cose che puoi fare. In effetti, potresti avere molti futuri, tutti indipendenti l'uno dall'altro, che potresti voler eseguire in parallelo, mentre aspetti che tutto sia completo.

Il timer fornisce solo un'attesa per ottenere risultati parziali.

+1

Ma dal momento che il problema della terminazione non è stato ancora risolto :), si ha alcuna garanzia che una funzione restituisce. Pertanto, i future potrebbero non tornare mai più. Quindi la domanda originale rimane ... Punto preso sull'attesa()() usato per tirare risultati parziali. Questo sembra un modello di utilizzo: passa in una classe che salva i risultati parziali mentre vengono generati, quindi utilizza il timer per estrarli. – DrGary

1

Penso che il motivo per cui il futuro non può essere semplicemente "ucciso" è esattamente lo stesso del perché java.lang.Thread.stop() è deprecated.

Mentre è in esecuzione Future, è necessaria una discussione. Per arrestare un futuro senza chiamare arresto() sul thread di esecuzione, è necessaria logica specifica applicazione: verifica di una bandiera specifica applicazione o lo stato interrotta del filo di esecuzione è periodicamente un modo per farlo.