The scala.concurrent.Future
API uses implicit arguments to reduce boilerplate in your code. They are another tool for concurrency provided by Scala. Akka uses Futures, but you can use them separately when you don’t need the full capabilities of actors.
When you wrap some work in a Future
, the work is executed asynchronously and the Future
API provides various ways to process the results, such as providing callbacks that will be invoked when the result is ready.
The following example fires off five work items concurrently and handles the results as they finish:
package com.brown
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
/**
* Created by BrownWong on 2016/9/29.
*/
object Hello {
def sleep(millis: Long) = {
Thread.sleep(millis)
}
// Busy word
def doWork(index: Int) = {
sleep((math.random*1000).toLong)
index
}
def main(args: Array[String]): Unit = {
(1 to 5) foreach { index =>
val future = Future{
doWork(index)
}
future onSuccess {
case answer: Int => println(s"Success! returned: $answer")
}
future onFailure {
case th: Throwable => println(s"Failure! returned: $th")
}
}
sleep(1000)
println("Finito!")
}
}
After the imports, we use a sleep
method to simulate staying busy for an arbitrary amount of time. The doWork
method simply calls it with a randomly generated number of milliseconds between 0 and 1000.
We iterate through a Range
of integers from 1 to 5
, inclusive, with foreach
and call scala.concurrent.Future.apply
, the “factory” method on the singleton object Future
. In this case Future.apply
is passed an anonymous function of work to do. We use curly braces instead of parentheses to wrap the no-argument anonymous function we pass to it.
Future.apply
returns a new Future
object, which executes the doWork(index)
body on another thread; control then immediately returns to the loop.
We then use onSuccess
to register a callback to be invoked if the future completes successfully. This callback function is a PartialFunction. Similarly, we use onFailure
to register a callback for failure handling, where the failure will be encapsulated in a Throwable
.
A final sleep
call waits before exiting to allow the work to finish.
output
Success! returned: 1
Success! returned: 2
Success! returned: 5
Success! returned: 3
Success! returned: 4
Finito!
Ref