while(true)和loop之间有什么区别?

时间:2009-08-16 09:51:45

标签: scala

我没有得到两个“表达式”之间的实际(语义)差异 据说“循环”适合“反应”和“而(真实)”适合“接收”,因为“反应”不会返回,“循环”是一个再次调用身体的功能(至少这是我从消息来源中扣除了什么 - 我对使用过的“andThen”并不熟悉。 “接收”阻止池中的一个线程,“反应”不会。但是,对于“反应”,查找可以附加功能的线程。

所以问题是:为什么我不能用“接收”来使用“循环”?它似乎与“while(true)”变体的行为不同(并且更好!),至少这是我在分析器中观察到的。 更奇怪的是,使用“-Dactors.maxPoolSize = 1 -Dactors.corePoolSize = 1”并使用“while(true)”和“receive”块立即调用乒乓(这是我所期望的) - 但是,“循环“和”接收“,它没有问题 - 在一个线程中 - 这是怎么回事?

谢谢!

2 个答案:

答案 0 :(得分:4)

whileloop之间的关键区别在于while限制循环迭代 在同一个帖子中发生loop构造(由 Daniel 描述)使actor子系统能够在它选择的任何线程上调用 react

因此,在receive中使用while (true)的组合将一个actor绑定到一个线程。使用loopreact 可以在单个帖子上运行支持多个角色

答案 1 :(得分:2)

方法loop在对象Actor中定义:

private[actors] trait Body[a] {
  def andThen[b](other: => b): Unit
}

implicit def mkBody[a](body: => a) = new Body[a] {
  def andThen[b](other: => b): Unit = self.seq(body, other)
}

/**
 * Causes <code>self</code> to repeatedly execute
 * <code>body</code>.
 *
 * @param body the code block to be executed
 */
def loop(body: => Unit): Unit = body andThen loop(body)

这很令人困惑,但会发生的事情是循环之后的块({}之间的东西)作为第一个参数传递给方法seq,并且带有该块的新循环作为第二个参数传递。

对于方法seq,在特征Actor中,我们发现:

private def seq[a, b](first: => a, next: => b): Unit = {
  val s = Actor.self
  val killNext = s.kill
  s.kill = () => {
    s.kill = killNext

    // to avoid stack overflow:
    // instead of directly executing `next`,
    // schedule as continuation
    scheduleActor({ case _ => next }, 1)
    throw new SuspendActorException
  }
  first
  throw new KillActorException
}

因此,新的循环被安排在kill之后的下一个动作,然后块被执行,然后抛出类型KillActorException的异常,这将导致循环再次执行。

因此,while循环执行速度比loop快得多,因为它不会抛出任何异常,也不执行调度等。另一方面,调度程序有机会在其间安排其他内容。两次执行loop