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"
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? –
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
Creare un 'ExecutionContext' da' Executors.newFixedThreadPool (1) 'con' implicit val executionContext = ExecutionContext.fromExecutorService (Executors.newFixedThreadPool (1)) '. – jpcooper