scala.concurrent.blocking的用例


73

我遇到了该scala.concurrent.blocking方法,根据Scala文档,这是...

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

我有些疑惑:

  • 产生新线程的因素是什么?
  • 这仅适用于scala.concurrent.ExecutionContext.Implicits.global执行上下文还是用户创建的执行上下文?
  • 如果我用blocking {...包装任何可执行文件,该}怎么办?
  • 我们应该使用此构造的任何实际用例。

Answers:


59
  1. 当新线程检测到fork / join池中的所有线程正在使用该join结构互相等待时,就会在fork / join池中生成新线程,并且还有更多工作可能完成其中一个线程。或者,如果ForkJoinWorker线程之一正在执行阻塞代码(而不是通过使用)join,则可以使用ManagedBlockers通知池。
  2. 它可能适用于任何类型的执行上下文-通知ExecutionContext实现由工作线程执行的代码在某些情况下可能阻塞,并且可以通过使用其他线程计算其他内容来解决此情况。执行上下文可以对此起作用,也可以不起作用。在当前的(2.10,2.11)实现中,blocking仅适用于默认的全局执行上下文。
  3. 如果用阻塞包装任何可执行文件,将会导致运行时开销,所以不要总是这样做。
  4. 如果您的计算会持续很长时间(例如几秒钟或几分钟),或者您正在等待将来完成使用Await,或者您正在等待监视器的状态得以解决,那么此状态可以通过其他一些任务/应该在同一执行上下文上执行的将来-在所有这些情况下,您应该使用blocking

编辑:

考虑看一下《Scala中的学习并发编程》第4章。


2
我们从使用中得到blocking什么?是否应该仅将其用于期货(而不是在主线程中)?
maks

您可以在任何地方使用它,但是它只会对辅助线程产生影响,即使用进行的计算Future { ... }
axel22


1
似乎人们对“最佳实践”代码示例的普遍兴趣在于如何执行此操作。
Mike Slinn 2014年

2
@Suma我同意axel22给出的定义(特别是第2点)下不能进行长时间运行的计算。长时间运行的计算不会从其他线程中进行的计算中受益,相反,它将获得较少的资源来完成。我只是遇到了使用akka EC(ForkJoin)和blocking {}并耗尽线程的情况,因为我们有2k的长时间计算没有及时完成。我想听到一个道理,即阻塞{}如何使长期运行的独立计算受益。
蒂姆(Tim)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.