【问题标题】:blocking keyword in ScalaScala中的阻塞关键字
【发布时间】:2015-09-10 20:46:55
【问题描述】:

Future(blocking(blockingCall()))blocking(Future(blockingCall())) 有什么区别?这两个都定义在scala.concurrent._

我查看了at the scala docs 和其他一些stack overflow answers,但仍不清楚有什么区别。

【问题讨论】:

    标签: scala concurrency io future


    【解决方案1】:

    blockingExecutionContext 提示它包含阻塞代码,以便它可以生成一个新线程以防止死锁。这假定 ExecutionContext 可以做到这一点,但并非所有的都这样做。

    让我们一个一个地看。


    Future(blocking(blockingCall()))
    

    这需要隐含的ExecutionContext 来执行Future。如果正在使用的ExecutionContextBlockContext(就像scala.concurrent.ExecutionContext.Implicits.global 一样),如果需要,它可能能够在其线程池中生成一个新线程来处理阻塞调用。如果不是,则没有什么特别的事情发生。


    blocking(Future(blockingCall()))
    

    这告诉我们Future(blockingCall())可能是一个阻塞调用,所以和上面一样处理。除了这里,Future.apply 是非阻塞的,所以使用blocking 只会增加一点开销。我们从这里调用什么 ExecutionContext 并不重要,因为它无论如何都不会阻塞。 然而,在Future 内的阻塞调用会阻塞它正在运行的ExecutionContext 中的线程,没有提示它的阻塞.所以,没有理由这样做。

    我已经在this answer 中更深入地解释了blocking


    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)) }
    

    【讨论】:

    • 它也不是关键字,它只是一种方法。
    • 这是一个很好的解释!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2013-04-03
    • 2015-09-22
    • 2016-02-29
    • 1970-01-01
    相关资源
    最近更新 更多