首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能创建自己的ExecutionContext来正确处理scala.concurrent.blocking?

是否有可能创建自己的ExecutionContext来正确处理scala.concurrent.blocking?
EN

Stack Overflow用户
提问于 2015-12-19 22:02:42
回答 1查看 239关注 0票数 2

我正在为基于ScheduledExecutorService的计时器编写close()方法:

代码语言:javascript
复制
override def close(implicit executionContext: ExecutionContext): Future[Unit] = {
  val p = Promise[Unit]
  executionContext.execute(new Runnable() {
    override def run() = {
      blocking { 
        p complete Try {
          executor.shutdown()
          //OK for default global execution context
          //As we marked this code as blocking, additional thread
          //will be used on that so no threadpool starvation
          executor.awaitTermination(1, TimeUnit.DAYS)
        }
      }
    }
  })
  p.future
}

但是如果我自己实现ExecutionContext,这段代码将阻塞池的一个线程,因为我没有找到任何方法来获得阻塞上下文。

那么,问题是:是否有可能创建自己的ExecutionContext来正确地处理scala.concurrent.blocking?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-19 22:33:16

当然,这是有可能的,只是它远不是微不足道的。您需要创建一个ExecutionContext来创建混合在BlockContext中的线程,这需要以下方法:

代码语言:javascript
复制
def blockOn[T](thunk: => T)(implicit permission: CanAwait): T

blocking(thunk)最终将导致调用blockOn(thunk),而blockOn应该知道ExecutionContext是否已经达到饥饿状态,是否需要做一些事情。scala.concurrent.ExecutionContext.Implicits.global完成了这边请,但是正如您所看到的,它使用ForkJoinPool来完成繁重的工作,实现就是https://github.com/scala/scala/blob/1fbce4612c21a4d0c553ea489b4765494828c09f/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java

请记住,无论是使用ExecutionContext.Implicits.global还是使用自己的“`ExecutionContext”,线程仍然会被代码阻塞。唯一的区别是前者产生了另一个线程来处理太多被阻塞的事实。但是,创建自己的线程可能会产生一些危险的bug,因为必须非常小心,以避免死锁或产生过多的线程。

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

https://stackoverflow.com/questions/34375843

复制
相关文章

相似问题

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