使用Scala中的共享非线程安全资源进行简单并行化

时间:2012-04-26 23:20:54

标签: multithreading scala parallel-processing

我经常想要并行化依赖于非线程安全共享资源的任务。考虑以下非线程安全类。我想在data: Vector[String]上做地图。

class Processor { def apply: String => String }

基本上,我想创建n个线程,每个线程都有一个Processor实例和一个数据分区。 Scala并行集合让我误以为并行化应该简单易懂。但是,它们似乎不适合这个问题。是的,我可以使用演员,但Scala演员可能会被弃用,Akka看起来有点矫枉过正。

首先想到的是拥有一个同步的地图Thread -> Processor然后使用并行集合,在这个线程安全的地图中查找我的Processor。还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用ThreadLocal,而不是构建自己的同步地图。这将保证每个线程唯一Processor

val processors = new ThreadLocal[Processor] {
  def initialValue() = new Processor
}

data.par.map(x => processors.get.apply(x))

答案 1 :(得分:0)

或者,您尝试使用配置为明确使用指定数量的线程的执行程序服务:

  val processors = new ThreadLocal[Processor] {
    override def initialValue() = new Processor
  }

  val N = 4

  // create an executor with fixed number of threads
  val execSvc = Executors.newFixedThreadPool(N)

  // create the tasks
  data foreach {
    loopData =>
      execSvc.submit(new Runnable() {
        def run = processors.get().apply(loopData)
      })
  }

  // await termination
  execSvc.shutdown()
  while(!execSvc.awaitTermination(1, TimeUnit.SECONDS)) {
    ;
  }

  // processing complete!