Scala Future [T]是否在内部阻塞?Scala Future内部会发生什么?

tom*_*ies 5 multithreading scala future threadpool

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

future.onComplete(_ => println("done"))
Run Code Online (Sandbox Code Playgroud)

上面的代码在以后的代码块中。

我的问题是:由于Future使用了ExecutionContext。这是否意味着该线程池中的某些线程在执行其中的代码时会被将来阻塞?

到底哪个线程会调用回调?来自线程池的另一个线程?它将如何发现在此将来执行的代码已完成?

Mic*_*jac 4

假设您正在调用阻止 a 的代码Future

由于 Future 使用ExecutionContext. 这是否意味着该线程池中的某些线程在执行其中的代码时将被该 future 阻塞?

本质上是的。如果您正在调用阻止代码,则必须阻止某些内容。不过, AnExecutionContext比线程池更通用。它可以是线程池,但也可以只是以其他方式管理调用的东西。尽管如此,有些东西还是会被阻塞,通常是一个线程。例如,scala.concurrent.ExecutionContext.Implicits.global是 a 。ForkJoinPool

到底哪个线程会调用回调?

这主要由他们ExecutionContext决定。您可以打印Thread.currentThread回调代码,但没有任何理由(除了调试之外)您确实需要了解此信息。您的代码当然不需要知道。通常,这意味着池中的下一个可用线程,它可以是执行 的主体的同一线程Future,也可以是不同的线程。看起来执行原始线程的同一个线程Future将调度回调,但这只是安排它们执行。

它如何知道这个 future 内的代码执行已经完成?

如果的底层处于已完成状态,则调用onComplete将立即执行,或者将被添加到监听器列表中,以便在 Promise 完成时执行。将在计算执行后立即调用侦听器。请参阅当前代码的摘录。PromiseFutureCallbackRunnableDefaultPromise#tryComplete