2013-04-19 11 views
7

Supponiamo di dover eseguire alcune attività simultanee.Quando potrebbero i Futures essere più appropriati degli attori (o viceversa) in Scala?

Posso avvolgere ogni attività in un Future e attendere il loro completamento. In alternativa, posso creare uno Actor per ogni attività. Ogni Actor eseguirà il proprio compito (ad es. Dopo aver ricevuto un messaggio "start") e restituirà il risultato.

Mi chiedo quando devo usare il primo (con Future s) e la seconda (con Actor s) avvicinamento e perché l'approccio Future è considerato migliore per il caso descritto sopra.

risposta

6

Perché è sintatticamente più semplice.

val tasks: Seq[() => T] = ??? 
val futures = tasks map { 
    t => future { t() } 
} 
val results: Future[Seq[T]] = Future.sequence(futures) 

Il results futuro si può quindi attendere sull'uso Await.result oppure si può mappare ulteriormente/usarla in per-di comprensione o installare le richiamate su di esso.

Confronti che, per istanziare tutti gli attori, l'invio di messaggi a loro, la codifica loro receive blocchi, ricevere risposte da loro e spegnimento - che in genere richiedono più boilerplate.

+0

Quindi, l'unica differenza è solo una sintassi. È corretto? – Michael

+2

La differenza è anche nell'implementazione sottostante, ma il modello di attore è in generale un modello di programmazione più potente ed espressivo: probabilmente potresti creare un'API simile all'API di Futures utilizzando gli attori. Implementare attori usando i futures sarebbe più complicato. – axel22

+0

Ok, vedo la differenza tra i modelli. Potresti spiegare anche la differenza in bianco e nero delle implementazioni? – Michael

5

Come regola generale, utilizzare il modello di concorrenza più semplice che si adatta all'applicazione, piuttosto che il più potente. Ordinare dal più semplice al più complesso sarebbe la programmazione sequenziale-> collezioni parallele-> futures-> attori stateless-> stateful actor-> thread con memoria transazionale software-> thread con lock esplicativo-> thread con algoritmi lock-free. Scegli il primo in questa lista che risolve il tuo problema. Più in basso si va all'elenco, maggiore è la complessità e i rischi, quindi è meglio scambiare la semplicità con il potere concettuale.

+0

Da dove hai preso quella sequenza? Per me, sembra incoerente, poiché l'uso dei futures implica discussioni con blocco esplicito. E, dove sono i thread con il blocco implicito (utilizzando la coda di blocco). Inoltre, di quanti input può avere il tuo attore? se solo uno (attori scala e akka), allora dovresti elencare gli attori multi-input separatamente. Se gli attori che intendi possono avere più input, non c'è differenza tra attori stateless e stateful (lo stato è un token passato a un input aggiuntivo). –

+1

La lista era solo un'opinione personale. I tuoi cambiamenti sono ragionevoli, eccetto che i futures non implicano in alcun modo thread e lock espliciti. I futures privi di effetti collaterali modellano in modo efficace le variabili del flusso di dati e ottengono la concorrenza senza consentire il non-determinismo. –

+0

I futures in Java (java.util.concurrent.Future) e nella maggior parte degli altri linguaggi (vedi http://en.wikipedia.org/wiki/Futures_and_promises) stanno bloccando, e quindi implicano i thread. Di quali futuri stai parlando? –

0

Tendo a pensare che gli attori siano utili quando si hanno thread di interazione. Nel tuo caso, sembra che tutti i lavori siano indipendenti; Userei i futures.

+1

Leggendo le altre risposte, penso che una nuova dovrebbe essere un po 'più elaborata. – manuell

Problemi correlati