Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Scala Future[T] block internally? What happens inside Scala Future?

val future = Future {
   println("hello")
   Thread.sleep(2000)
}

future.onComplete(_ => println("done"))

The code in the future above blocks.

My question is: since Future uses an ExecutionContext. Does it mean that some thread in this thread pool will be blocked by this future while executing the code inside it?

What thread exactly will call the callback? Another thread from the thread pool? How will it find out that the code executed inside this future is finished?

like image 925
tomdavies Avatar asked Mar 27 '17 20:03

tomdavies


1 Answers

Assuming you're calling code that blocks in a Future:

since Future uses ExecutionContext. Does it mean, that some thread in this thread pool will be blocked by this future while executing the code inside it?

Essentially, yes. If you're calling blocking code, something has to be blocked. An ExecutionContext is more general than a thread pool, though. It can be thread pool, but it can also be just something that manages calls in some other way. Still, something will be blocked, more often than not it will be a thread. scala.concurrent.ExecutionContext.Implicits.global is a ForkJoinPool, for example.

What thread exactly will call the callback?

That is mostly up to the ExecutionContext to decide. You can print Thread.currentThread in your callback code, but there is no reason (other than maybe debugging) why you really need to know this information. Your code certainly shouldn't need to know. Typically this means the next available thread in the pool, which could be the same thread that executed the body of the Future, or a different one. It appears that the same thread that executes the original Future will dispatch the callbacks, but that only schedules them for execution.

How will it find out, that the code execution inside this future is finished?

Calling onComplete will either execute immediately if the underlying Promise of the Future is in the completed state, or a CallbackRunnable will be added to a list of listeners to be executed when the promise is completed. DefaultPromise#tryComplete will call the listeners immediately after the computation has executed. See this excerpt of the current code.

like image 78
Michael Zajac Avatar answered Nov 15 '22 06:11

Michael Zajac