Scala.concurrent.blocking的使用案例

76

我发现了scala.concurrent.blocking方法,根据Scala文档所述,这是...

用于指定可能会阻塞的代码片段,允许当前的BlockContext调整运行时的行为。正确地标记阻塞代码可以提高性能或避免死锁。

我有一些疑问:

  • 新线程所需的因素是什么?
  • 这只适用于scala.concurrent.ExecutionContext.Implicits.global执行上下文还是对用户创建的执行上下文也适用?
  • 如果我使用blocking { ... }包装任何可执行文件,会发生什么?
  • 何时应该使用此结构的任何实际用例。
1个回答

65
  1. 当检测到fork/join池中的所有线程都在使用join构造等待彼此时,并且有更多工作需要完成,可能会完成其中一个线程时,新的线程将在fork/join池中生成。或者,如果ForkJoinWorker线程之一正在执行代码而不是使用join阻塞其他线程,则可以使用ManagedBlocker通知池。
  2. 它可能适用于任何种类的执行上下文——它作为通知ExecutionContext实现,指示由工作线程执行的代码可能在某些条件上阻止,并且这种条件可能通过使用其他线程计算其他内容来解决。执行上下文可以采取行动,也可能不采取行动。在当前(2.10、2.11)实现中,blocking仅适用于默认全局执行上下文。
  3. 如果用blocking包装任何可执行文件,您将引入一些运行时开销,因此不要总是这样做。
  4. 如果您有一个需要很长时间(例如几秒钟或几分钟)才能计算出结果的计算,或者正在使用Await等待完成的future,或者正在等待监视器的条件变为确定,而此条件可以由应在同一执行上下文中运行的某些其他任务/future解决——在所有这些情况下,都应使用blocking

编辑:

请考虑查看《Scala并发编程入门》第4章。


2
使用“阻塞”带来了什么好处?这应该只用于未来(而不是主线程)中吗? - maks
你可以在任何地方使用它,但它只会对工作线程产生影响,即使用 Future { ... } 执行的计算。 - axel22
已在此找到答案 https://dev59.com/D2cs5IYBdhLWcg3wJQm8 - maks
1
似乎有一般兴趣了解如何进行“最佳实践”的代码示例。 - Mike Slinn
2
@Suma 我同意长时间运行的计算不适合axel22给出的定义,特别是第二点。长时间运行的计算不会从其他线程计算的工作中受益,相反它将获得更少的资源来完成。我刚遇到这样一种情况,我们使用了akka EC(ForkJoin)和blocking{},由于有2k个这样的长时间计算没有及时完成,我们用完了所有线程。我想听听如何证明blocking{}对于长时间独立计算的好处。 - Tim
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接