如何最好地实例化执行上下文?

时间:2015-11-12 04:00:33

标签: multithreading scala scala-2.11

我正在建立一个其他人的图书馆 - 即。那些对内部不感兴趣的人 - 可以用来从我们的数据库中提取数据。在内部,我希望并行执行几个I / O调用以达到性能目的。这里的权衡是客户端(再次,可能不关心整个线程事物)需要提供适当的执行上下文。因此,我提供了在辅助对象中使用有用的执行上下文的建议:

object ThreadPoolHelper {
  val cachedThreadPoolContext: ExecutionContext =
    ExecutionContext.fromExecutor(Executors.newCachedThreadPool())
}

问题是(假设有一天我还提供其他选项,比如说,一个固定的线程池供客户端选择使用)我还好这个(这些)作为val吗?或者我最好让它变得懒惰?还是def?

1 个答案:

答案 0 :(得分:2)

懒散的方式就是这样或那样。

使它们lazy val成为一个很好的通用选择,因为每个都可以根据需要进行初始化(因为它们被访问)。然后,您永远不会初始化比所需更多的线程池。 scala.concurrent.ExecutionContext.Implicits.globalimplicit lazy val

从技术上讲,单例对象(如ThreadPoolHelper)在默认情况下是惰性的,因此在首次访问它们之前不会对它们进行初始化。如果ExecutionContext中只有一个object,那么val就可以了。但是,同一个对象中的多个ExecutionContext作为val并不是很有意义,因为访问一个会将它们全部初始化 - 这会占用比所需更多的资源。

def没有意义,因为那样你就会在每次通话时创建一个新的ExecutionContext,并在完成后扔掉它。这可能会导致很多不必要的开销,并默认首先拥有一个线程池。

一些比你更自定义的ExecutionContext是单身object,它们扩展ExecutionContext并实现自己的自定义行为。这些也很懒惰。