Secuencia futura en Scala
-
Ejecutar
Futuros
secuencialmente en Scala - Ejecución Concurrente/Paralela de Futuros en Scala
- Conclusión
En este artículo, aprenderemos sobre los futuros
en Scala.
En Scala, Futuro
es un valor que puede no estar disponible actualmente pero lo estará en el futuro.
Cuando queremos ejecutar tareas concurrentemente/paralelamente en Scala, usamos Futures
. Aunque podríamos usar un hilo
nativo de Java, se prefiere Scala Future
ya que es mucho más simple de escribir.
En pocas palabras, Future
proporciona formas sencillas de ejecutar un algoritmo/aplicación al mismo tiempo. Cuando se crea un futuro, comienza a ejecutarse al mismo tiempo y da resultados en algún punto que eventualmente es en algún punto en el que obtenemos los resultados.
Ejecutar Futuros
secuencialmente en Scala
Cuando futuros
comienza a ejecutarse secuencialmente, es una ejecución secuencial. Tenemos que importar ExecutionContext
, que administra el grupo de subprocesos; sin ella, el futuro
no correrá.
Veamos un ejemplo para entenderlo mejor.
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Example extends App {
def task(n: Int) = Future
{
Thread.sleep(1000)
println(n) //to observe the output
n + 1
}
//running in a sequential way
val temp = for {
t1 <- task(1)
t2 <- task(t1)
t3 <- task(t2)
t4 <- task(t3)
t5 <- task(t4)
} yield List(t1,t2,t3,t4,t5)
temp.map(x => println(s"Completed. ${x.size} tasks were executed"))
Thread.sleep(5000) //so that the main thread doesn't quit quickly
}
Cuando se ejecuta el código, vemos que nuestras 5 tareas se ejecutan en orden secuencial, una tras otra.
Ejecución Concurrente/Paralela de Futuros en Scala
Código de ejemplo:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Example extends App {
def task(n: Int) = Future
{
Thread.sleep(1000)
println(n) //to observe the output
n + 1
}
val temp = for {
t1 <- task(1)
t2 <- Future.sequence(List(task(t1), task(t1)))
t3 <- task(t2.head)
t4 <- Future.sequence(List(task(t3), task(t3)))
t5 <- task(t4.head)
} yield t2.size + t4.size
temp.foreach(x => println(s"Done. $x task run in concurrent manner"))
Thread.sleep(6000) // needed to prevent the main thread from quitting
// too early
}
En el código anterior, hemos utilizado Future.sequence
, que toma la lista de futuros
y los convierte en un futuro de lista
. Todas las tareas/trabajos que queremos ejecutar simultáneamente deben pasarse como una lista.
Producción:
Cuando se ejecuta el código anterior, vemos que t2
y t4
se ejecutan en paralelo. Una cosa que debe recordar al trabajar con paralelismo es que la ejecución no siempre puede ser paralela, ya que depende de la disponibilidad de los subprocesos.
Si solo hay algunos subprocesos presentes, solo unos pocos trabajos se ejecutarán en paralelo mientras otros esperan a que se liberen los subprocesos.
Conclusión
En este tutorial, entendimos qué son los Futuros
y cómo son útiles para escribir y ejecutar programas simultáneamente.