首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将来包装的同步HTTP请求是否被认为是CPU或IO绑定的?

将来包装的同步HTTP请求是否被认为是CPU或IO绑定的?
EN

Stack Overflow用户
提问于 2020-07-26 14:03:36
回答 1查看 778关注 0票数 2

考虑以下两个片段,其中第一个用Future包装scalaj-http请求,而第二个使用异步-http-客户机。

使用全局EC封装未来的同步客户端

代码语言:javascript
复制
object SyncClientWithFuture {
  def main(args: Array[String]): Unit = {
    import scala.concurrent.ExecutionContext.Implicits.global
    import scalaj.http.Http
    val delay = "3000"
    val slowApi = s"http://slowwly.robertomurray.co.uk/delay/${delay}/url/https://www.google.co.uk"
    val nestedF = Future(Http(slowApi).asString).flatMap { _ =>
      Future.sequence(List(
        Future(Http(slowApi).asString),
        Future(Http(slowApi).asString),
        Future(Http(slowApi).asString)
      ))
    }
    time { Await.result(nestedF, Inf) }
  }
}

使用全局EC的异步客户端

代码语言:javascript
复制
object AsyncClient {
  def main(args: Array[String]): Unit = {
    import scala.concurrent.ExecutionContext.Implicits.global
    import sttp.client._
    import sttp.client.asynchttpclient.future.AsyncHttpClientFutureBackend
    implicit val sttpBackend = AsyncHttpClientFutureBackend()
    val delay = "3000"
    val slowApi = uri"http://slowwly.robertomurray.co.uk/delay/${delay}/url/https://www.google.co.uk"
    val nestedF = basicRequest.get(slowApi).send().flatMap { _ =>
      Future.sequence(List(
        basicRequest.get(slowApi).send(),
        basicRequest.get(slowApi).send(),
        basicRequest.get(slowApi).send()
      ))
    }
    time { Await.result(nestedF, Inf) }
  }
}

片段正在使用

前者需要12秒,后者需要6秒。前者的行为似乎是受CPU约束的,但我看不出情况是怎样的,因为Future#sequence应该并行执行HTTP请求?为什么在Future中包装的同步客户端行为与正确的异步客户端不同?异步客户端不是做了同样的事情吗?它将调用包装在“期货”中吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-03 23:41:35

Future#sequence应该并行执行HTTP请求吗?

首先,Future#sequence不执行任何操作。它只生成一个在所有参数完成时完成的未来。如果EC中有一个自由线程,则对已构建期货的评估(执行)立即开始。否则,它只是将其提交给某种队列。我相信,在第一种情况下,你有单线程执行期货。

println(scala.concurrent.ExecutionContext.Implicits.global) ->并行=6

不知道为什么会这样,可能其他5个线程总是因为某种原因而忙碌。您可以使用5-10个线程显式地创建新的EC。

与异步情况不同的是,您不是自己创建未来,而是由库提供的,内部不阻塞线程。它启动异步进程,“订阅”一个结果,并返回未来,这将在结果出现时完成。

实际上,异步库内部可以有另一个EC,但我怀疑。

顺便说一句,如果没有blocking,期货不应该包含缓慢/io/阻塞评估。否则,您可能会阻塞主线程池(EC),您的应用程序将被完全冻结。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63101178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档