【问题标题】:Is there a way to get a non-global clone of scala.concurrent.ExecutionContext.global?有没有办法获得 scala.concurrent.ExecutionContext.global 的非全局克隆?
【发布时间】:2014-05-17 23:57:13
【问题描述】:

我正在寻找 ForkJoinPool 的非全局实例,以便获得全局实例的所有出色的默认并行性和执行语义,并能够控制池的生命周期。

我查看了scala.concurrentscala.concurrent.impl, 的源代码,可悲的是,看起来创建默认实例的所有代码都是private[scala.concurrent],并且也没有间接调用代码的方法。

我只能使用ExecutionContext.fromExecutor(null) 获得具有默认设置的ExecutionContext 的新实例,但无法获取底层ForkJoinPool。也没有办法直接关闭ExecutionContext

我是否在做一些我不应该做的深奥的事情?因为对我来说,想要的东西似乎很自然:没有全局性的东西的默认语义/配置。

【问题讨论】:

    标签: scala concurrency threadpool executorservice fork-join


    【解决方案1】:

    这不是访问问题,而是形状问题。大象的尾巴:

    scala> type ECI = { def createExecutorService: ExecutorService }
    defined type alias ECI
    
    scala> val fjp = ExecutionContext.global.asInstanceOf[ECI].createExecutorService
    fjp: java.util.concurrent.ExecutorService = scala.concurrent.forkjoin.ForkJoinPool@606dff1[Running, parallelism = 8, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
    

    或无形:

    scala> import shapeless.syntax.typeable._
    import shapeless.syntax.typeable._
    
    scala> val fjp = concurrent.ExecutionContext.global.cast[ECI] map (_.createExecutorService) getOrElse ???
    fcp: java.util.concurrent.ExecutorService = scala.concurrent.forkjoin.ForkJoinPool@45c26421[Running, parallelism = 8, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
    

    然后

    scala> val eces = ExecutionContext fromExecutorService fjp
    eces: scala.concurrent.ExecutionContextExecutorService = scala.concurrent.impl.ExecutionContextImpl$$anon$1@1df3794c
    
    scala> eces.shutdown
    

    【讨论】:

    • 不知道我怎么错过了它这么简单的一点……非常感谢! :)
    【解决方案2】:

    private[path.to.package] 的好处在于,您可以通过 假装在该软件包中来解决它

    package scala.concurrent
    
    import java.util.concurrent.Executor
    
    object Foo {
      implicit lazy val myGlobalExecutionContext: ExecutionContextExecutor =
        impl.ExecutionContextImpl.fromExecutor(null: Executor)
    }
    

    但是,请注意,如果您这样做,您将不再处于 public API 领域,并且在更改 scala 版本时将不得不处理某些不兼容问题。

    【讨论】:

    • 好的,这很明显;之前并没有真正想到这一点:) 顺便说一句,您的代码仍然没有获得默认池本身,只是默认执行上下文,但我想我可以调整它以获取底层池。
    • 几个小时前我还不知道这个功能,直到我观看了最新的scalawags 剧集,其中 Josh Suereth 解释了它为什么存在以及它是如何荒谬的有帮助。
    • 我不接受/赞成,只是想看看我是否能从中得到一些其他的意见;如果没有,代表是你的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多