使用Scala actor和receiveWithin的Stackoverflow异常

时间:2011-05-25 08:25:34

标签: scala actor

一段时间后,这个演员填写了堆栈。可能的解决方案?

object Puller extends Actor {

 def act() = {
  receiveWithin(2000) {
    case Stop => println("stoping puller")
        exit()
    case Noop => println("nothing happens")
        act()
    case TIMEOUT => doPull
        act()
  }
}

  def doPull() = // stuff...
}

我不开心找到这个程序代码在Scala中。

2 个答案:

答案 0 :(得分:4)

好吧,它堆栈溢出的原因非常明显;它是递归的,但不是尾递归的。这里有两个选择:

:使用while循环:

def act() = 
  while(true) {
    receiveWithin(2000) {
      case Stop    => println("stoping puller"); exit()
      case Noop    => println("nothing happens")
      case TIMEOUT => doPull
    }
  }

:使用loopreact(通过将玩家与占用单个线程分离,可以实现可扩展性的附加好处)。

def act() = 
  loop {
    reactWithin(2000) {
      case Stop    => println("stoping puller"); exit()
      case Noop    => println("nothing happens")
      case TIMEOUT => doPull
    }
  }

如果此代码存在于 Scala编程中,它可能更多地是作为概念验证,而不是可行的生产代码。实际上,从内存中,它继续解释了如何避免递归act调用。

答案 1 :(得分:4)

您的act不是尾递归的。您可以按如下方式修改它:

  @tailrec // in the presence of this annotation, the compiler will complain, if the code is not tail-recursive
  def act() = {
    receiveWithin(2000) {
      case Stop => println("stoping puller"); exit()
      case Noop => println("nothing happens")
      case TIMEOUT => doPull
    }
    act()
  }
相关问题