2

在我的 Scala 2.9.2 队列上操作时,我收到一个不常见的 NoSuchElementException 错误。我不明白这个例外,因为队列中有元素。我尝试切换到 SynchronizedQueue,认为这是一个并发问题(我的队列是从不同的线程写入和读取的),但这并没有解决它。

精简后的代码如下所示:

val window = new scala.collection.mutable.Queue[Packet]
...
(thread 1)
window += packet
...
(thread 2)
window.dequeueAll(someFunction)
println(window.size)
window.foreach(println(_))

这导致

32
java.util.NoSuchElementException
    at scala.collection.mutable.LinkedListLike$class.head(LinkedListLike.scala:76)
    at scala.collection.mutable.LinkedList.head(LinkedList.scala:78)
    at scala.collection.mutable.MutableList.head(MutableList.scala:53)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.mutable.MutableList.foreach(MutableList.scala:30)

LinkedListLike.head() 的文档说

 Exceptions thrown
 `NoSuchElementException`
 if the linked list is empty.

但是如果队列不为空,怎么会抛出这个异常呢?

4

1 回答 1

0

您应该window仅从单个线程访问(可变数据结构)。其他线程应该向那个线程发送消息。

Akka允许相对简单的并发编程。

class MySource(windowHolderRef:ActorRef) {
  def receive = {
    case MyEvent(packet:Packet) =>
      windowHolderRef ! packet
  }
}

case object CheckMessages

class WindowHolder {
  private val window = new scala.collection.mutable.Queue[Packet]
  def receive = {
    case packet:Packet =>
      window += packet
    case CheckMessages =>
      window.dequeueAll(someFunction)
      println(window.size)
      window.foreach(println(_))
  }
}

要定期检查消息,您可以安排定期消息。

  // context.schedule(1 second, 1 second, CheckMessages)
于 2013-09-23T06:41:22.307 回答