6

このプログラムは、main()を実行した後、終了しません。

object Main
{
    def main(args: Array[String]) {
        ... // existing code
        f()
        ... // existing code
    }
    def f() {
        import scala.actors.Actor._
        val a = actor {
            loop {
                react {
                case msg: String => System.out.println(msg)
                }
            }
        }
        a ! "hello world"
    }
}

この予期しない副作用のために、アクターの使用は煩わしいと見なされる可能性があります。

アクターがプログラムの終了まで実行し続ける必要があると仮定すると、終了のすべての場合に元の動作を維持するにはどうすればよいですか?

4

2 に答える 2

7

2.8には、これを可能にするDaemonActorクラスがあります。2.7.xでは、ライブアクターがまだ存在する場合でもシャットダウンを妨げないカスタムスケジューラをハックできます。または、メインの最後でSystem.exit()を呼び出す簡単な方法が必要な場合もあります。

アクターを一種の軽量スレッドと考える場合、多くの場合、ライブアクターがプログラムの終了を防ぐ必要があります。そうでなければ、アクターですべての作業を行うプログラムがある場合、すべてのアクターが終了するまでそれを存続させるためだけに、メインスレッドに何かを置く必要があります。

于 2010-02-21T13:11:29.860 に答える
4

上記の例のメインスレッドが完了した後も、プログラムにはまだアクターを実行している非デーモンスレッドがありました。通常、Thread.destroy()またはSystem.exit()を使用して実行中のスレッドを残酷に終了することはお勧めできません。データの破損やデッドロックなど、プログラムに非常に悪い結果が生じる可能性があります。そのため、そもそもThread.destroy()などのメソッドがJavaで非推奨になりました。正しい方法は、スレッドに終了ロジックを明示的に実装することです。Scalaアクターの場合、実行中のすべてのアクターに停止メッセージを送信し、メッセージを受け取ったら終了させます。このアプローチでは、サンプルは次のようになります。

object Main
{
    case object Stop
    def main(args: Array[String]) {
        ... // existing code
        val a = f()
        a ! "hello world"
        ... // existing code
        a ! Stop
    }
    def f() = {
        import scala.actors.Actor._
        actor {
            loop {
                react {
                   case msg: String => System.out.println(msg)
                   case Stop => exit()
                }
            }
        }
    }
}
于 2010-02-22T05:59:10.933 に答える