在Scala中阻塞关键字 [英] blocking keyword in Scala

查看:296
本文介绍了在Scala中阻塞关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

未来(blocking(blockingCall())阻塞(Future(blockingCall())之间有什么区别?这两个都定义在 scala.concurrent ._

What's the difference between Future(blocking(blockingCall())) and blocking(Future(blockingCall()))? Both of these are defined in scala.concurrent._

我看过 scala docs 和其他一些

I've looked at the scala docs and some other stack overflow answers but remain unclear on what the difference is.

推荐答案

blocking 充当提示 ExecutionContext ,它包含阻止代码,可能产生一个新的线程以防止死锁。这假设 ExecutionContext 可以这样做,但不是所有的。

blocking acts as a hint to the ExecutionContext that it contains blocking code, so that it may spawn a new thread to prevent deadlocks. This presumes the ExecutionContext can do that, but not all are made to.

让我们看看每个一-one。

Let's look at each one-by-one.

Future(blocking(blockingCall()))

这需要一个隐式的 ExecutionContext $ c>未来。如果使用的 ExecutionContext BlockContext (如 scala.concurrent.ExecutionContext.Implicits。全局是),它可能能够在其线程池中产生一个新线程来处理阻塞调用,如果需要的话。

This requires an implicit ExecutionContext to execute the Future. If the ExecutionContext being used is a BlockContext (like scala.concurrent.ExecutionContext.Implicits.global is), it may be able to spawn a new thread in its thread pool to handle the blocking call, if it needs to. If it isn't, then nothing special happens.

blocking(Future(blockingCall()))

可能是一个阻塞调用,因此它被视为与上述相同。除了这里, Future.apply 是非阻塞的,因此使用阻塞实际上不会增加​​一点开销。不管什么 ExecutionContext 我们从这里调用它,因为它不会阻塞。 未来内的阻止调用会阻塞 ExecutionContext code>它正在运行,没有暗示它的阻塞。

This tells us that Future(blockingCall()) may be a blocking call, so it is treated the same as above. Except here, Future.apply is non-blocking, so using blocking effectively does nothing but add a little overhead. It doesn't matter what ExecutionContext we're calling it from here, as it isn't blocking anyway. However, the blocking call within the Future will block a thread in the ExecutionContext it's running on, without the hint that its blocking. So, there is no reason to ever do this.

我在中更深入地解释了 blocking href =http://stackoverflow.com/questions/29068064/scala-concurrent-blocking-what-does-it-actually-do/29069021#29069021>此答案

I've explained blocking more in depth in this answer.

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

这篇关于在Scala中阻塞关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆