【问题标题】:Scala/Akka NullPointerException on master actor主演员上的 Scala/Akka NullPointerException
【发布时间】:2014-12-26 00:57:32
【问题描述】:

我正在学习 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
  }
}

【问题讨论】:

    标签: java scala parallel-processing akka


    【解决方案1】:

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

    【讨论】:

    • 感谢修复,但堆栈跟踪无法指出它
    【解决方案2】:

    你的计算会停止吗?排队

    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-in-actors-only-with-contextbecome

    【讨论】:

      猜你喜欢
      • 2019-04-23
      • 2014-06-13
      • 2018-05-23
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2013-02-06
      相关资源
      最近更新 更多