我有以下代码:
def sync = Action {
val t0 = System.nanoTime()
Thread.sleep(100)
val t1 = System.nanoTime()
Ok("Elapsed time: " + (t1 - t0) / 1000000.0 + "ms")
}
def async = Action {
val t0 = System.nanoTime()
Async {
Future{
Thread.sleep(100)
val t1 = System.nanoTime()
Ok("Elapsed time: " + (t1 - t0) / 1000000.0 + "ms")
}
}
}
上述代码的区别在于,sync 将在接收请求的线程上休眠,而 async 将在单独的线程上休眠,以便负责接收请求的线程可以继续接收请求而不会阻塞。当我分析线程时,我发现为异步请求创建的线程数量按预期突然增加。然而,上述两种方法(4000 个并发连接 20 秒斜坡)会产生相同的吞吐量和延迟。我希望异步能够表现得更好。为什么会这样呢?
简而言之,这两种方法本质上是相同的。
操作本身始终是异步的(请参阅有关处理异步结果的文档 http://www.playframework.com/documentation/2.3.0/ScalaAsync).
在这两种情况下,sleep
调用发生在操作的线程池中(这不是最佳的)。
如中所述了解 Play 线程池 http://www.playframework.com/documentation/2.3.x/ThreadPools:
Play 框架从下到上是一个异步 Web 框架。使用迭代器异步处理流。 Play 中的线程池经过调整,使用比传统 Web 框架更少的线程,因为 play-core 中的 IO 永远不会阻塞。
因此,如果您计划编写阻塞 IO 代码,或者可能执行大量 CPU 密集型工作的代码,您需要确切地知道哪个线程池正在承担该工作负载,并且需要相应地对其进行调整。
例如,此代码片段使用单独的线程池:
Future {
// Some blocking or expensive code here
}(Contexts.myExecutionContext)
作为其他资源,请参阅这个答案 https://stackoverflow.com/a/24004444/376366 and 有关处理异步操作的更多信息和this https://groups.google.com/forum/#!topic/play-framework/WWQ0HeLDOjg and this https://groups.google.com/forum/#!topic/play-framework/yzwBa2afFcs论坛消息,用于对该主题进行广泛讨论。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)