6

This program, after executing main(), does not exit.

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"
    }
}

Because of this unexpected side-effect, using actors can be viewed as intrusive.

Assuming the actors must continue to run until program termination, how would you do to preserve original behavior in all cases of termination?

4

2 回答 2

7

在 2.8 中有一个 DaemonActor 类允许这样做。在 2.7.x 中,您可以修改自定义调度程序,即使仍有现场演员,也不会阻止关机,或者如果您想要一种简单的方法,您可以在 main 结束时调用 System.exit()。

如果您将 actor 视为一种轻量级线程,那么很多时候您希望使用 live actor 来防止程序终止。否则,如果您有一个程序在演员中完成所有工作,则您需要在主线程上放置一些东西以使其保持活动状态,直到所有演员完成。

于 2010-02-21T13:11:29.860 回答
4

上例中的主线程完成后,程序仍然有一个非守护线程运行actor。使用 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 回答