Home > Blockchain >  await vs while !fut.isCompleted
await vs while !fut.isCompleted

Time:12-01

I have the next code:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main extends App {

  println("Hello, World!")

  val fut = Future { Thread.sleep(10000); 21   21 }

  while (!fut.isCompleted)
    {}

  println(fut.value)

}

What is the advantage of using Await instead of the while loop? Is it better to use the while loop? why?

I am trying to understand Scala Futures

Thanks

CodePudding user response:

Await should be less CPU-intensive than a while loop.

The implementation you'll get with most Futures is going to eventually be using def tryAwait from Promise, which you can see is using CompletionLatch, which under the hood is using some low-level thread synchronization functionality so that it can actually just stall the calling thread until the latch is released. Meanwhile your CPU can go do other things and "ignore" that thread.

As opposed to while (!fut.isCompleted) which is just going to spend every possible CPU cycle running that check.

However, as @gatear already mentioned, you typically won't ever call Await.ready(...). Typically you will attach some behavior to the future so that it will run when the result becomes available (i.e. let the Future tell things are ready, rather than being like a child in the back seat of a car, constantly asking "are we there yet?"). For example:

val loadGoogleHtml: Future[String] = /* ... */

loadGoogleHtml.onComplete {
  case Success(html) => println(s"loaded google.com --\n$html")
  case Failure(err) => err.printStackTrace()
}

Or you could create a new Future that applies some post-processing to the first future, e.g.

val loadGoogleHtmlAsXml: Future[XML] = {
  loadGoogleHtml.map { rawHtml => parseRawXml(rawHtml) }
}

The point of using Future is to help you out when you have some value that will eventually be available (e.g. some IO operation like communicating with a remote server, or a long computation that's being run on a separate thread or thread-pool), where that result is communicated via a callback function; Future is effectively a nicer way to interact with that callback-based design.

CodePudding user response:

Working with async code in Scala you'll probably interact with a framework that will either take or give you a Future[T].

In a prod environment don't wait in a while block for a Future.
If you really need to do it use Await:

  import scala.concurrent.duration._

  Await.result(fut, 1 minute) //will return the result
  Await.ready(fut, 1 minute)  //or just await for completion

Both block but regarding your question here is a snippet from the Scala doc:
Although this method is blocking, the internal use of [[scala.concurrent.blocking blocking]] ensures that the underlying [[ExecutionContext]] is given an opportunity to properly manage the blocking.

To understand some real life use-case here is how you define async actions in Play Framework.

  • Related