我试图理解 blocking
构造。虽然它内部是如何工作的并不完全清楚,但我得到的一般想法是,只要我使用 Scala 的全局线程池,用 blocking
包装我的代码。上下文将确保线程池为该作业创建额外的空间(因为它不受 CPU 限制)。
(1 to 1000).foreach { i =>
Future {
println(i)
Thread.sleep(100 * 1000)
}
}
将很快表明只有 8 个作业可以同时运行,而
(1 to 1000).foreach { i =>
Future {
blocking {
println(i)
Thread.sleep(100 * 1000)
}
}
}
将显示现在我们有大约 250 个同时工作。哇!
然后让我措手不及的是
(1 to 1000).foreach { i =>
Future {
println(i)
Thread.sleep(100 * 1000)
}
}
('a' to 'z').foreach { c =>
Future {
blocking {
println(c)
Thread.sleep(100 * 1000)
}
}
}
将再次只显示 8 个并发作业——阻塞作业不会立即执行。
为什么是这样?
blocking
的内部机制到底是什么?语境?
最佳答案
blocking
只有在您进入阻塞上下文后才会生效。由于您有 8 个非阻塞 future 在运行,因此不会启动任何新 future ,因此它们无法进入阻塞上下文。换句话说,Scala 不会“知道”它们在开始执行之前正在阻塞。
您可以将第二个代码段视为如下工作:
blocking
表示它正在阻塞,因此实现为更多 future 腾出了空间。 而你的最后一个片段是这样工作的:
blocking
来告诉实现它正在阻塞。 . 关于multithreading - Scala 的阻塞上下文似乎不适用于混合阻塞/非阻塞作业。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55365841/