开发者

How can I add scala actors to an existing program without interfering with the normal termination behavior?

开发者 https://www.devze.com 2022-12-20 16:28 出处:网络
This program, after executing main(), does not exit. 开发者_开发技巧object Main { def main(args: Array[String]) {

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?


In 2.8 there's a DaemonActor class that allows this. In 2.7.x I you could hack in a custom scheduler that doesn't prevent shutdown even if there are still live actors, or if you want an easy way you could call System.exit() at the end of main.

If you think of an actor as kind of a light-weight thread, much of the time you want a live actor to prevent program termination. Otherwise if you have a program that does all of its work in actors, you'd need to have something on the main thread just to keep it alive until all the actors finish.


After the main thread in the above example completed, the program still had a non-daemon thread running the actor. It is usually a bad idea to brutally terminate running threads using Thread.destroy() or System.exit() for results may be very bad for your program including, but not limited to, data corruption and deadlocks. That is why Thread.destroy() and alike methods were deprecated in Java for the first place. The right way would be to explicitly implement termination logic in your threads. In case of Scala actors that boils down to sending a Stop message to all running actors and make them quit when they get it. With this approach your eample would look like this:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号