なんじゃくにっき

プログラミングの話題中心。

Scala de Design Pattern: Thread Pool

 Worker Threadパターンとも。
スレッドの生成はコストが大きいので、
あらかじめ複数のスレッドを生成しておき、貯めておく
(この貯められたスレッドの集合をスレッドプールと呼ぶ)。
スレッドが必要になったらスレッドプールからスレッドを呼び出し、
使い終えたらスレッドはスレッドプールに返して再利用する。
Object Poolのスレッド版。
 
 
 ScalaのActorはスレッドプール上で動作している。
http://www.scala-lang.org/node/242
 
ので、自分でスレッドプールを書かなくてもOK。
というわけでコードなし。
 
 
といいたいところだが、Actor Poolみたいな変なものを書いてみた。
メリットはあまりない気がする。
 

import scala.actors._
import scala.util.Random

class HogeActor(name: String) extends Actor {
def act() = {
loop {
react {
case f : Function1[String, Unit] => {
f(name)
}
}
}
}
}

object Main {
def main(args: Array[String]) = {
// Actorを3つ生成して開始
val actorPool =
for(i <- 0 to 2)
yield new HogeActor("Actor" + i.toString)
actorPool.foreach(_.start())

// 送り先のActorをランダムに決めてメッセージを割り振るobject
object loadBalancer {
val random = new Random
def send(message: Any) = {
actorPool((random.nextFloat * 3.0).toInt) ! message
}
}

// メッセージを表示する関数を生成してloadBalancerに投げる
for (i <- (1 to 10)) {
val func = (s: String) => println(s + ": Message" + i)
loadBalancer.send(func)
}
}
}

 
実行結果

Actor1: Message2
Actor0: Message3
Actor2: Message1
Actor2: Message5
Actor0: Message6
Actor0: Message7
Actor1: Message4
Actor1: Message8
Actor1: Message9
Actor1: Message10
 
Actorを複数生成して、関数をランダムに投げているだけ。
関数すらメッセージとしてActorに送れるのがいいっすね。