自分の問題に対するより良い解決策を見つけたと思います。揮発性変数を使用して操作が終了するタイミングを知らせる代わりに、より優先度の高い終了メッセージをアクターに送信できます。次のようになります。
val a = new Actor() {
def act():Unit = {
loop{ react {
case "Exit" => exit(); return;
case MyMessage => {
//this check makes "Exit" a high priority message, if "Exit"
//is on the queue, it will be handled before proceeding to
//handle the real message.
receiveWithin(0) {
case "Exit" => exit(); return
case TIMEOUT => //don't do anything.
}
sender ! "hi!" //reply to sender
}
}}
}
}
a.start()
val f = a !! MyMessage
while( ! f.isSet && a.getState != Actor.State.Terminated ) {
//will probably return almost immediately unless the Actor was terminated
//after I checked.
Futures.awaitAll(100,f)
}
if( a.getState != Actor.State.Terminated ) {
f() // the future should evaluate to "hi!"
}
a ! "Exit" //stops the actor from processing anymore messages.
//regardless of if any are still on the queue.
a.getState // terminated
おそらくこれを書くためのよりクリーンな方法があります..しかし、それは私がアプリケーションで行ったこととほぼ同じです。
キューに「Exit」メッセージがない限り、reactWithin(0) は即時の no-op です。キューに入れられた「Exit」メッセージは、スレッド化された Java アプリケーションに入れる揮発性ブール値を置き換えます。