2015-04-21 12 views
9

Utilizzando il contesto di esecuzione implicito predefinito in Scala, ciascun nuovo futuro verrà calcolato su un singolo thread dedicato o il calcolo verrà diviso e distribuito a più thread nel pool di thread?I futures sono eseguiti su un singolo thread? (Scala)

Non so se questo aiuti, lo sfondo di questa domanda è che voglio eseguire più operazioni simultanee utilizzando l'API HtmlUnit. Per fare questo, vorrei avvolgere ogni nuova istanza WebClient in un futuro. L'unico problema è che la classe WebClient non è thread-safe, quindi sono preoccupato che potrebbe essere suddiviso e inviato a thread diversi.

risposta

14

Un futuro viene eseguito su un singolo thread. Diversi futuri potrebbero essere eseguiti su più thread. Quindi, non più che in futuro, possiamo occupare un thread simultaneamente.

Come funziona? Quando crei un Futuro significa che hai inviato l'attività al tuo pool di thread: questa attività non può essere parallelamente implicita in modo che venga eseguita su un solo thread. Una o più attività inviate al pool vengono inserite nella coda del pool, quindi l'esecutore prende le attività da quella coda una alla volta ed esegue ciascuna su un thread scelto casualmente (o intenzionalmente). Quindi molti Futures possono arrivare a diversi thread.

Informazioni sull'oggetto condiviso: l'unico modo per eseguire le operazioni in modo sicuro per l'oggetto condiviso tra i futures è utilizzando Executors.newFixedThreadPool(1), verrà utilizzato un solo thread per l'intero pool. Un'altra soluzione - è quella di clonare tale oggetto per ogni futuro. Usare gli attori (rendere il tuo oggetto condiviso lo stato di un attore) dovrebbe essere l'opzione migliore.

Se si utilizza un oggetto per il futuro, tutto dovrebbe andare bene.

Nota: il gestore del futuro, come Future{ ... }.map(handler), può essere eseguito in thread diversi rispetto al futuro stesso, ma in realtà crea un altro Future per ottenere un risultato. Lo stesso per flatMap. Più precisamente, usano onComplete che crea CallbackRunnable lanciare handler (possibile in thread differente), dopo il successo storico di futuro - questo callback appena completato futuro newely creato, quindi ancora "non più di un thread per il futuro"

+0

Grazie! Questa era esattamente l'informazione che stavo cercando. Solo una rapida domanda di follow-up: c'è qualche vantaggio nell'inoltrare più futures a un nuovo FixedThreadPool con un solo thread? I calcoli possono essere concomitanti su un singolo thread? –

+0

Nessun vantaggio in termini di prestazioni. L'unica cosa che potrebbe darti è l'API asincrona (invia più attività + iscriviti al completamento). Puoi anche creare diverse piscine per diversi tipi di futuro, ma gli attori sono molto meglio per questo. – dk14

+1

Creare un 'ExecutionContext' da' Executors.newFixedThreadPool (1) 'con' implicit val executionContext = ExecutionContext.fromExecutorService (Executors.newFixedThreadPool (1)) '. – jpcooper

-1

Un Future[+T] non può garantire che sarà completato sullo stesso thread se è composto da più futures. Detto questo, ciò non significa che otterrai un'eccezione di modifica simultanea o qualcosa del genere. È ancora possibile eseguire il codice asincrono in sequenza, nel qual caso sarebbe sicuro.

Per quanto riguarda la seconda domanda, finché si dispone di un'istanza per ogni futuro non si dovrebbero avere problemi di concorrenza.

+0

se componendo intendi qualcosa come ['Future.sequence'] (https://github.com/scala/scala/blob/2.11.x/src/library/scala/concurrent/Future.scala) - creano solo un nuovo futuro di successo con il corpo vuoto (quindi non eseguito affatto da nessuna parte) e quindi aggiungendo i gestori (i gestori di whichadd al futuro nella composizione). Quindi il futuro stesso viene eseguito in thread singolo; comunque gestori ('Futuro.map') potrebbe essere eseguito in diversi, ma ogni nuovo gestore restituisce un * diverso * futuro – dk14

+0

Quindi, la sequenza sta producendo diversi nuovi futuri, ma nessun * singolo * futuro da essi può essere assegnato a più di un thread. – dk14

+0

Mi riferisco all'uso di flatMap o per la comprensione sui futures. –

Problemi correlati