1

スレッドセーフではない共有リソースに依存するタスクを並列化したいことがよくあります。次の非スレッドセーフクラスについて考えてみます。上の地図を作りたいですdata: Vector[String]

class Processor { def apply: String => String }

基本的に、それぞれがデータのインスタンスとパーティションをn持つスレッドを作成したいと思います。ProcessorScalaの並列コレクションは、並列化は単純なものであるべきだと私を甘やかしてしまいました。ただし、この問題にはあまり適していません。はい、私はアクターを使用できますが、Scalaアクターは非推奨になる可能性があり、Akkaはやり過ぎのようです。

最初に頭に浮かぶのは、同期されたマップThread -> Processorを作成してから、並列コレクションを使用してProcessor、このスレッドセーフなマップで自分を検索することです。もっと良い方法はありますか?

4

2 に答える 2

1

独自の同期マップを作成する代わりに、 を使用できますThreadLocalProcessorこれにより、スレッドごと に一意が保証されます。

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

data.par.map(x => processors.get.apply(x))
于 2012-04-27T13:57:25.120 に答える
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!
于 2012-04-27T16:30:04.903 に答える