如何创建一个与ExecutionContext.global具有类似属性的附加ExecutionContext?

时间:2014-11-12 22:36:50

标签: scala

在Scala中,据我所知,ExecutionContext.global与通常使用ExecutionContext创建的其他ExecutionContext.fromExecutor(...)对象不同,因为它可以使用scala.concurrent.blocking作为信号当最初的小线程池被长时间运行,可能是io-bound计算阻塞时,产生额外的线程。有没有办法创建另一个这样的ExecutionContext?查看源代码,似乎ExecutionContext.global以相当独特的方式创建,通过内部调用impl.ExecutionContextImpl.fromExecutor(null: Executor),即包私有。

1 个答案:

答案 0 :(得分:1)

所以你可以用这个很容易地创建它:

  scala.concurrent.ExecutionContext.fromExecutor(null)

它将完成与ExecutionContext.global完全相同的过程。

在幕后,这只是创建一个ForkJoinPool,其中包含一个特殊ThreadFactory来处理scala.concurrent.blocking信号。如果您想要更多控制权,可以创建自己的ForkJoinPool,然后提供ThreadFactory做类似于scala版本的操作(source):

  class DefaultThreadFactory(daemonic: Boolean) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
    def wire[T <: Thread](thread: T): T = {
      thread.setDaemon(daemonic)
      thread.setUncaughtExceptionHandler(uncaughtExceptionHandler)
      thread
    }

    def newThread(runnable: Runnable): Thread = wire(new Thread(runnable))

    def newThread(fjp: ForkJoinPool): ForkJoinWorkerThread = wire(new ForkJoinWorkerThread(fjp) with BlockContext {
      override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
        var result: T = null.asInstanceOf[T]
        ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
          @volatile var isdone = false
          override def block(): Boolean = {
            result = try thunk finally { isdone = true }
            true
          }
          override def isReleasable = isdone
        })
        result
      }
    })
  }

此外,Akka对FJP也有启示。