Scala には、マルチスレッド処理を簡素に実現できる Actor ライブラリがあります。Actor ライブラリは、Actor 間でのメッセージのやり取りが処理をブロックすることなく行うことができます。
簡単な非同期メッセージの送信と受信
まずは簡単な例で動作を確認してみます。Actor として Friend を作成し、Hi というメッセージと Bye というメッセージを送信してみます。
import scala.actors.Actor import scala.actors.Actor._ case object Hi //メッセージをケースクラスとして定義 case object Bye //メッセージをケースクラスとして定義 class Friend extends Actor { def act() { while(true) { receive { case Hi => println("Friend: hello") case Bye => println("Friend: bye"); exit() } } } } object Main extends Application { val friend = new Friend friend.start friend ! Hi // Hi メッセージの送信 friend ! Bye // Byeメッセージの送信 }
Mainオブジェクトでfriendを作成し、メッセージを送っています。実行結果は以下のようになります。
Friend: hello Friend: Bye
メッセージの送信にFriendが答えてくれました。
Mainクラスを以下のように変更した場合どのようになるでしょう。
object Main extends Application { val friend = new Friend friend ! Hi friend.start friend ! Hi friend ! Bye }
startする前にHiメッセージを送信しています。実行結果は以下のようになります。
Friend: hello Friend: hello Friend: Bye
以下のようにすると実行結果としては何も表示されません。
object Example200 extends Application { val friend = new Friend friend ! Hi friend ! Bye }
つまりHiというメッセージは送信され、キューに入れられ、friend.startによりメッセージの処理が開始されていることになります。
簡単な同期メッセージの送信と受信
上で見たメッセージの送信は非同期メッセージでした。つまり、friend ! Hi の呼出はブロックされません。これを少し詳しく見てみましょう。
import scala.actors.Actor import scala.actors.Actor._ case object Hi case object Bye class Friend extends Actor { def act() { while(true) { receive { case Hi => println("Friend: hello") Thread.sleep(1000) // <--- reply() // <--- case Bye => println("Friend: bye"); exit() } } } } object Main extends Application { val friend = new Friend friend.start println("Hi"); friend ! Hi println("Bye"); friend ! Bye }
実行結果は以下のようになりました。
Hi Bye Friend: hello Friend: bye
Mainオブジェクトを「friend ! Hi」→「friend !? Hi」に書き変えてみます。
object Main extends Application { val friend = new Friend friend.start println("Hi"); friend !? Hi println("Bye"); friend ! Bye }
実行結果は以下のようになります。
Hi Friend: hello Bye Friend: bye
「Friend: hello」を表示後、1秒ほどして「Bye」が表示されました。これは「friend !? Hi」が同期メッセージの送信となり、処理がブロックされたことを意味します。(ちなみにreply()を記述しない場合には、「friend !? Hi」のメッセージ送信が永遠にブロックされ続けます)
ここでは簡単にActorライブラリの使い方を見てみました。
次回はもう少し詳しく見ていきたいと思います。