我花了一段时间学习了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,见hereBlockContext通常只是混合了Thread特征的BlockContext。从源代码中可以看出,它要么存储在ThreadLocal中,要么在其中找不到,它与当前线程匹配。如果当前线程不是BlockContext,则使用DefaultBlockContext代替。

接下来,在当前blockOn上调用BlockContextblockOnBlockContext中的抽象方法,因此其实现取决于ExecutionContext处理它的方式。如果我们查看implementation for DefaultBlockContext (当当前线程不是BlockContext时),我们看到blockOn实际上在那里什么也不做。因此,在非blocking中使用BlockContext意味着完全不需要做任何特别的事情,并且该代码按原样运行,没有副作用。

那么BlockContext的线程呢?例如,在global上下文中,看到hereblockOn的功能还很多。深入研究,您会发现它在后台使用了ForkJoinPool,并且在同一片段中定义的DefaultThreadFactory用于在ForkJoinPool中生成新线程。如果没有从blockOn(线程)中实现BlockContext,则ForkJoinPool不会知道您正在阻塞,也不会尝试生成更多线程作为响应。

Scala的 Await 也使用blocking实现。

关于scala - scala.concurrent.blocking-它实际上是做什么的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29068064/

10-11 04:53