Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Play Framework:以阻塞方式调用async future时,新线程的创建没有限制_Multithreading_Scala_Asynchronous_Playframework 2.0 - Fatal编程技术网

Multithreading Play Framework:以阻塞方式调用async future时,新线程的创建没有限制

Multithreading Play Framework:以阻塞方式调用async future时,新线程的创建没有限制,multithreading,scala,asynchronous,playframework-2.0,Multithreading,Scala,Asynchronous,Playframework 2.0,我有以下代码: import scala.concurrent.ExecutionContext.Implicits.global def index = Action { Ok(Await.result(callSync, 10.seconds).body) } def callSync = { WS.url("http://yahoo.jp").get } 基本上,WS.url将返回未来的[WS.Response],因此在上面的代码中,我希望在以阻

我有以下代码:

 import scala.concurrent.ExecutionContext.Implicits.global

  def index = Action {
      Ok(Await.result(callSync, 10.seconds).body)
  }

  def callSync = {
    WS.url("http://yahoo.jp").get
  }
基本上,WS.url将返回未来的[WS.Response],因此在上面的代码中,我希望在以阻塞方式调用时监视此服务的行为。在我的操作中,我等待结果,然后显示响应主体。我正在尝试使用20sec ramp的2000个并发用户执行此操作。问题是上面的代码创建了大量新线程,play实例关闭了错误“java.lang.OutOfMemoryError:无法创建新的本机线程”。这完全不是预期的行为。我使用的是默认的执行上下文,所以这个池将只有核心+1个线程。为什么上面会创建大量线程

改为这样做:

import play.api.libs.concurrent.Promise

def index = Action.async {
  Future.firstCompletedOf(List(
    callsync.map(x => Ok(x.body)),
    Promise.timeout(Ok("an error occurred"), 10.seconds)
  ))
}

wait.result
scala.concurrent.blocking
包装阻塞等待结果,通知
ExecutionContext
它正在阻塞。默认的
ExecutionContext
由一个fork-join池支持,该池将很快耗尽,因为它只有与内核相同的线程数,相反,它将生成一个新线程,以保持非阻塞操作的可用线程数不变。

我不确定,但如果有2000个用户触发您的操作,
callSync
不会被调用2000次,从而产生多个线程吗?在我看来,这似乎是正确的行为,您的操作的用户访问量应由您决定,而不是由框架决定,除非我遗漏了一些内容。我希望一些请求会被拒绝,因为所有现有线程在某个时候都被占用,以阻塞方式处理请求。我认为未来{blocking{}}是play根据需要创建额外线程的唯一方式。如果您能解释一下为什么上面的代码没有超时并引发异常,而不是创建大量线程,那就太好了。我不想做以上的工作,我想找一个解释为什么它会这样做。谢谢这是有道理的。奇怪的是,如果显式使用Future{{blocking{},这个测试实际上可以在没有由于大量线程创建而关闭播放的情况下运行(它是通过在某个点上稳定创建的)。wait.result和Future{blocking{}的行为应该是相同的。。。