例えば、javaのThreadを使って以下のようなコードを実行する。
1 to 10 map( n => (new Thread() { override def run = { println("start "+n) Thread.sleep( 3000 ) println("done "+n) } }).start )結果の出力は、以下のように、ほぼ同時に10個のスレッドがスタートして、 3秒後にそれぞれ終了する。
これは、予想通り。
start 10 start 4 start 6 start 2 start 3 start 8 start 9 start 7 start 1 start 5 done 10 done 4 done 6 done 2 done 3 done 8 done 9 done 7 done 1 done 5これをActorを使って書き換える。
1 to 10 map( n => Actor.actor { println("start "+n) Thread.sleep( 3000 ) println("done "+n) })このコードを実行した結果。
start 1 start 6 start 8 start 7 start 3 start 5 start 2 start 4 done 1 done 6 done 8 start 9 start 10 done 3 done 7 done 4 done 2 done 5 done 9 done 10この結果をみると、最初の8個のスレッドは、ほぼ同時にスタートしているのがわかるが、 残りの2つは、最初にスタートしたスレッドが終わるのを待ってから、3秒後にそれぞれスタートしている。
なぜ?
どうやらこれはActorのプールに関係しているらしい。
詳しくは分からないが、Thread.sleepを使った場合、 並列に実行できるのは、CPUのスレッド数のみのようだ。
それ以上に、並列に実行したいので、Thread.sleepを使わずに、 receiveWithinを使ったらうまくいった。
1 to 10 map( n => Actor.actor { println("start "+n) Actor.self.receiveWithin( 3000 ) { case TIMEOUT => {}} println("done "+n) })仕方ないので、この方法でやるかなぁ。
0 件のコメント:
コメントを投稿