我花了一段时间学习了Scala执行上下文,底层线程模型和并发的主题。您能否解释scaladoc中描述的scala.concurrent.blocking
以什么方式“调整运行时行为”和“可以提高性能或避免死锁”?
在the documentation中,它作为等待未实现Awaitable的api的一种方式提供。 (也许还应该包装长时间运行的计算?)。
它实际上是做什么的?
Following through the source不会轻易出卖其 secret 。
最佳答案
blocking
旨在作为ExecutionContext
的提示,表明所包含的代码正在阻塞并且可能导致线程饥饿。这将使线程池有机会产生新线程,以防止饥饿。这就是“调整运行时行为”的含义。但这并不是魔术,并且不会与每个ExecutionContext
一起使用。
考虑以下示例:
import scala.concurrent._
val ec = scala.concurrent.ExecutionContext.Implicits.global
(0 to 100) foreach { n =>
Future {
println("starting Future: " + n)
blocking { Thread.sleep(3000) }
println("ending Future: " + n)
}(ec)
}
这使用默认的全局
ExecutionContext
。按原样运行代码,您会注意到100个Future
都立即执行,但是如果删除blocking
,它们一次只会执行几个。默认的ExecutionContext
将通过生成新线程来响应阻塞调用(标记为此类),因此不会因运行Future
而超载。现在来看一个带有4个线程的固定池的示例:
import java.util.concurrent.Executors
val executorService = Executors.newFixedThreadPool(4)
val ec = ExecutionContext.fromExecutorService(executorService)
(0 to 100) foreach { n =>
Future {
println("starting Future: " + n)
blocking { Thread.sleep(3000) }
println("ending Future: " + n)
}(ec)
}
此
ExecutionContext
并不是为处理产生新线程而构建的,因此即使在我的阻塞代码被blocking
包围的情况下,您也可以看到它仍然一次最多只能执行4个Future
。这就是为什么我们说它“可以提高性能或避免死锁”的原因-无法保证。正如我们在后面的ExecutionContext
中看到的那样,根本无法保证。它是如何工作的?作为链接,
blocking
执行以下代码:BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission)
BlockContext.current
从当前线程中检索BlockContext
,见here。 BlockContext
通常只是混合了Thread
特征的BlockContext
。从源代码中可以看出,它要么存储在ThreadLocal
中,要么在其中找不到,它与当前线程匹配。如果当前线程不是BlockContext
,则使用DefaultBlockContext
代替。接下来,在当前
blockOn
上调用BlockContext
。 blockOn
是BlockContext
中的抽象方法,因此其实现取决于ExecutionContext
处理它的方式。如果我们查看implementation for DefaultBlockContext
(当当前线程不是BlockContext
时),我们看到blockOn
实际上在那里什么也不做。因此,在非blocking
中使用BlockContext
意味着完全不需要做任何特别的事情,并且该代码按原样运行,没有副作用。那么
BlockContext
的线程呢?例如,在global
上下文中,看到here,blockOn
的功能还很多。深入研究,您会发现它在后台使用了ForkJoinPool
,并且在同一片段中定义的DefaultThreadFactory
用于在ForkJoinPool
中生成新线程。如果没有从blockOn
(线程)中实现BlockContext
,则ForkJoinPool
不会知道您正在阻塞,也不会尝试生成更多线程作为响应。Scala的
Await
也使用blocking
实现。关于scala - scala.concurrent.blocking-它实际上是做什么的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29068064/