Question

I (a newbie) am testing my concepts about Scala's Futures and the right patterns to use them.

The premise
Scala's futures are blocks of code to be executed asynchronously. So, the main thread creates one or more such futures, installs onSuccess() [note: equally applicable to OnComplete/onFailure] callbacks and proceeds. The callbacks are executed as and when the futures complete their runs.

Presumably, these callbacks generate results which are supposed to be used by the main thread. The results are stored in a Try[T] container, with a write-once/read-many constraint. The main (or any other thread but that is not the point) decide when to peak in the container and collect the results for further processing.

Whichever discussion/blog/API I have laid my eyes on so far, mentions the fact that main thread doesn't have to wait: it can carry on doing its own thing, allowing the futures to be executed in parallel and be ready with the result.

Question

But my question is: in the simplest case, where it has finished doing whatever it is doing, the main thread will have to wait for the callbacks to finish, will it not? And, because there is no interruption mechanism provided which can indicate that the future has finished execution, the main thread has no option but to 'wait' (possibly with a time-limit) for the result to be ready? In other words, in an application, where futures are employed, a wait is ultimately unavoidable, isn't it?

Note
I understand that we can chain the futures, using combinators or Promise (and there are other patterns too), to avoid this issue altogether. But, I am trying to clarify my concept that under certain cases, using futures doesn't obviate the need to wait for them to finish.

Is it too elementary a question? Is it showing a big void in my understanding?

Was it helpful?

Solution

It would be useful to understand the theoretical difference between Await and async. These are known as blocking and non-blocking respectively.

Blocking

A blocking computation is much like a while loop.

while(!done) {
  if (isDone) {
    // do whatever
    done = true
  }
}

This is synchronous blocking computation. The Thread can't do anything else until the blocking action is complete as its constantly checking for the action.

You only really have as many threads as processors on the machine. Hopefully you can see how they can quickly be fully occupied and a giant FIFO queue of "things to do" is formed.

Non-blocking

In essence, the concept is very simple. Instead of continuously checking if something is done, the check is done at given time intervals. The Future will be checked for completion every 100ms(let`s say).

The awesome thing is during every one of those 100ms breaks, the Thread is free to do something else. That's why you get superior performance from async things.

Bottom line

It's physically possible for the processors to do more things in a given time interval. It's a very simple syllogism.

Say you and your friend arrange to meet for coffee at 3PM. He doesn't show up.

You can either sit in the coffee shop relentlessly cursing or you can go home and bake cookies. While the cookies are baking, you check your phone every 5 minutes until he eventually texts and then you meet up.

In scenario 1, you are angry and haven't done much all day.

In scenario 2, you are delighted by your culinary success and in a great mood to see a friend.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top