繁体   English   中英

主演员上的Scala / Akka NullPointerException

[英]Scala/Akka NullPointerException on master actor

我正在学习用于Scala中并行处理的Akka框架,并且试图将Java项目迁移到Scala,以便可以同时学习Akka和Scala。 在工作线程中进行一些计算后,尝试从工作角色中接收可变对象时,我在主角色上收到NullPointerException。 所有代码都在下面...

    import akka.actor._
    import java.math.BigInteger
    import akka.routing.ActorRefRoutee
    import akka.routing.Router
    import akka.routing.RoundRobinRoutingLogic

    object Main extends App {

      val system = ActorSystem("CalcSystem")
      val masterActor = system.actorOf(Props[Master], "master")
      masterActor.tell(new Calculate, ActorRef.noSender)
    }

    class Master extends Actor {

      private val messages: Int = 10;
      var resultList: Seq[String] = _

      //val workerRouter = this.context.actorOf(Props[Worker].withRouter(new RoundRobinRouter(2)), "worker")

      var router = {
        val routees = Vector.fill(5) {
          val r = context.actorOf(Props[Worker])
          context watch r
          ActorRefRoutee(r)
        }
        Router(RoundRobinRoutingLogic(), routees)
      }

      def receive() = {
        case msg: Calculate =>
          processMessages()
        case msg: Result =>
          resultList :+ msg.getFactorial().toString
          println(msg.getFactorial())

          if (resultList.length == messages) {
            end
          }
      }

      private def processMessages() {
        var i: Int = 0
        for (i <- 1 to messages) {
         // workerRouter.tell(new Work, self)
          router.route(new Work, self)
        }
      }

      private def end() {
        println("List = " + resultList)
        this.context.system.shutdown()
      }
    }


import akka.actor._
import java.math.BigInteger

class Worker extends Actor {

  private val calculator = new Calculator

  def receive() = {
    case msg: Work =>
      println("Called calculator.calculateFactorial: " + context.self.toString())
      val result = new Result(calculator.calculateFactorial)
      sender.tell(result, this.context.parent)

    case _ =>
      println("I don't know what to do with this...")

  }
}


import java.math.BigInteger

class Result(bigInt: BigInteger) {

  def getFactorial(): BigInteger = bigInt

}

import java.math.BigInteger

class Calculator {

  def calculateFactorial(): BigInteger = {

    var result: BigInteger = BigInteger.valueOf(1)
    var i = 0

    for(i <- 1 to 4) {      
      result = result.multiply(BigInteger.valueOf(i))      
    }        
    println("result: " + result)
    result
  }
}

resultList使用null初始化resultList ,然后尝试添加一些内容。

您的计算会停止吗? 排队

resultList :+ msg.getFactorial().toString

您正在创建序列副本,并附加了一个元素。 但是没有赋给var resultList

这条线将根据需要工作。

resultList = resultList :+ msg.getFactorial().toString

我建议您避免在actor中使用可变变量并使用context.become https://github.com/alexandru/scala-best-practices/blob/master/sections/5-actors.md#52-should-mutate-state-在只与- contextbecome演员,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM