有什么区别Future(blocking(blockingCall()))
and blocking(Future(blockingCall()))
?这两个都定义在scala.concurrent._
我看过在 scala 文档中 http://docs.scala-lang.org/overviews/core/futures.html#blocking和其他一些堆栈溢出答案 https://stackoverflow.com/questions/13097754/asynchronous-io-in-scala-with-futures#answer-13099594但仍不清楚有什么区别。
blocking
充当提示ExecutionContext
它包含阻塞代码,以便它可以生成一个新线程以防止死锁。这假设ExecutionContext
可以做到这一点,但并非所有人都能做到。
让我们一一来看。
Future(blocking(blockingCall()))
这需要一个隐式的ExecutionContext
执行Future
。如果ExecutionContext
被使用是一个BlockContext
(like scala.concurrent.ExecutionContext.Implicits.global
是),如果需要的话,它可能能够在其线程池中生成一个新线程来处理阻塞调用。如果不是,那么就没有什么特别的事情发生。
blocking(Future(blockingCall()))
这告诉我们Future(blockingCall())
可能是阻塞调用,所以处理方式与上面相同。除了这里,Future.apply
是非阻塞的,所以使用blocking
实际上除了增加一点开销之外什么也没做。什么都没关系ExecutionContext
我们从这里调用它,因为它无论如何都不会阻塞。However,阻塞调用within the Future
会阻塞一个线程ExecutionContext
它正在运行,without其阻塞的提示。因此,没有理由这样做。
我已经解释过了blocking
更深入地这个答案 https://stackoverflow.com/questions/29068064/scala-concurrent-blocking-what-does-it-actually-do/29069021#29069021.
REPL 示例:
import java.util.concurrent.Executors
import scala.concurrent._
val ec = scala.concurrent.ExecutionContext.Implicits.global
val executorService = Executors.newFixedThreadPool(4)
val ec2 = ExecutionContext.fromExecutorService(executorService)
def blockingCall(i: Int): Unit = { Thread.sleep(1000); println("blocking call.. " + i) }
// Spawns enough new threads in `ec` to handle the 100 blocking calls
(0 to 100) foreach { i => Future(blocking(blockingCall(i)))(ec) }
// Does not spawn new threads, and `ec2` reaches thread starvation
// execution will be staggered as threads are freed
(0 to 100) foreach { i => Future(blocking(blockingCall(i)))(ec2) }
// `blocking` does nothing because the `Future` is executed in a different context,
// and `ec2` reaches thread starvation
(0 to 100) foreach { i => blocking(Future(blockingCall(i))(ec2)) }
// `blocking` still does nothing, but `ec` does not know to spawn new threads (even though it could)
// so we reach thread starvation again
(0 to 100) foreach { i => blocking(Future(blockingCall(i))(ec)) }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)