我经常想要并行化依赖于非线程安全共享资源的任务。考虑以下非线程安全类。我想在data: Vector[String]
上做地图。
class Processor { def apply: String => String }
基本上,我想创建n
个线程,每个线程都有一个Processor
实例和一个数据分区。 Scala并行集合让我误以为并行化应该简单易懂。但是,它们似乎不适合这个问题。是的,我可以使用演员,但Scala演员可能会被弃用,Akka看起来有点矫枉过正。
首先想到的是拥有一个同步的地图Thread -> Processor
然后使用并行集合,在这个线程安全的地图中查找我的Processor
。还有更好的方法吗?
答案 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!