scala - play - 如何用 futures 包装阻塞代码

标签 scala asynchronous playframework future

我试图了解这两种方法在功能方面的区别。

class MyService (blockService: BlockService){
   def doSomething1(): Future[Boolean] = {
       //do
       //some non blocking
       //stuff
       val result = blockService.block()
       Future.successful(result)
   }

   def doSomething2(): Future[Boolean] = {
       Future{
          //do
          //some non blocking
          //stuff
          blockService.block()
       }
   }
}

据我了解,两者之间的区别在于哪个线程是将被阻塞的实际线程。

因此,如果有一个线程:thread_1 执行 something1,thread_1 将被阻塞,而如果 thread_1 执行 something2,则新线程将运行它- thread_2,thread_2 是要被阻塞的那个。

这是真的吗?

如果是这样,那么就没有真正的首选方式来编写这段代码?如果我不关心哪个线程最终会被阻塞,那么最终的结果都是一样的。 dosomething1 似乎是一种奇怪的编写此代码的方式,我会选择 dosomething2

有道理吗?

最佳答案

是的,doSomething1doSomething2 会阻塞不同的线程,但根据您的场景,这是一个重要的决定。

正如@AndreasNeumann 所说,您可以在doSomething2 中有不同的执行上下文。假设主执行上下文是从您的用户接收 HTTP 请求的上下文。在此上下文中阻塞线程是不好的,因为您可以轻松耗尽执行上下文并影响与 doSomething 无关的请求。

Play docs对阻塞代码可能出现的问题有更好的解释:

If you plan to write blocking IO code, or code that could potentially do a lot of CPU intensive work, you need to know exactly which thread pool is bearing that workload, and you need to tune it accordingly. Doing blocking IO without taking this into account is likely to result in very poor performance from Play framework, for example, you may see only a few requests per second being handled, while CPU usage sits at 5%. In comparison, benchmarks on typical development hardware (eg, a MacBook Pro) have shown Play to be able to handle workloads in the hundreds or even thousands of requests per second without a sweat when tuned correctly.

在您的例子中,这两种方法都是使用 Play 默认线程池执行的。我建议你看看recommended best practices并查看您是否需要不同的执行上下文。我还建议您阅读关于 Dispatchers 的 Akka 文档和 Futures更好地了解执行 Future 的内容以及具有阻塞/非阻塞代码。

关于scala - play - 如何用 futures 包装阻塞代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35522466/

相关文章:

斯卡拉玩 : How to inject test Database into Controller for testing

java - @ {'/path/to/static_content' } 在 PlayFramework 中有什么意义?

mysql - 将 Biginteger 转换为 long 会导致错误

scala - 到处使用 Option 感觉有点尴尬。难道我做错了什么?

scala - 在 Scala 中编写 read-while 循环的正确方法是什么?

scala - 为什么在 Option[T] 的 HList 上映射不起作用?

python - 在 Flask 中创建一个异步任务

java - 如何将对象添加到未参数化的 Java 列表?

c++11 - 为什么在使用异步操作时没有堆栈溢出?

javascript - 异步,回调,关闭,哦,我的