如何在不干扰正常终止行为的情况下将scala actor添加到现有程序?

时间:2010-02-21 11:44:48

标签: scala exit actor termination

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

由于这种意想不到的副作用,使用演员可被视为侵入性。

假设参与者必须继续运行直到程序终止,您将如何在所有终止案例中保留原始行为?

2 个答案:

答案 0 :(得分:7)

在2.8中有一个允许这样的DaemonActor类。在2.7.x我可以破解自定义调度程序,即使仍有实时actor也不会阻止关闭,或者如果你想要一个简单的方法,你可以在main的末尾调用System.exit()。

如果你认为一个演员是一种轻量级线程,那么大多数时候你想要一个现场演员来防止程序终止。否则,如果你有一个程序在actor中完成它的所有工作,你需要在主线程上有一些东西,只是为了让它保持活着直到所有演员完成。

答案 1 :(得分:4)

在上面例子中的主线程完成之后,程序仍然有一个运行actor的非守护进程线程。使用Thread.destroy()或System.exit()粗暴地终止正在运行的线程通常是一个坏主意,因为结果可能对您的程序非常不利,包括但不限于数据损坏和死锁。这就是为什么Thread.destroy()和类似的方法首先在Java中被弃用的原因。正确的方法是在线程中显式实现终止逻辑。在Scala actor的情况下,归结为向所有正在运行的actor发送Stop消息并在它们获得它时让它们退出。使用这种方法,您的样本将如下所示:

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()
                }
            }
        }
    }
}