是否可以在 Akka Actor 的 actor 函数中定义线程?

Is it possible to define a thread within a function of an actor in Akka Actor?

假设我有一个 actor class,在 Akka Actor 中有一个方法:

class SecureActor extends Actor{
  def methodWithThread(): Unit={
}

可以运行在这个方法中创建一个新线程吗? Akka自己的线程不会有问题吗?

class ThreadExample extends Thread{  
    override def run(){  
      println("Thread is running...");  
}
def methodWithThread(): Unit={
  var t = new ThreadExample()  
  t.start()
}

既然你说你正在寻找如何确保你想要从 Akka Actor 创建异步任务的这种方式会破坏它提供给你的 Akka 并发模式,这里有一些非常简单的基于示例在你的 类.

这不是我在评论中建议的演示如何从父 actor 生成子 actor 的答案。正如您还所说,您有兴趣演示如何打破 Akka 并发模式。我建议您寻找有关如何做到这一点的简单示例。也许 this example 有帮助。

import akka.actor.{Actor, ActorSystem, Props}

import scala.util.Random

object BreakingAkkaConcurrency {
  def main(args: Array[String]): Unit = {
    val actorSystem = ActorSystem("BreakingAkkaConcurrency")
    val unsecureActor = actorSystem.actorOf(Props[UnsecureActor], "unsecureActor")
    unsecureActor ! "1"
    unsecureActor ! "2"
    unsecureActor ! "3"
    unsecureActor ! "4"
    unsecureActor ! "5"
    unsecureActor ! "6"
    unsecureActor ! "7"
    unsecureActor ! "8"
    unsecureActor ! "9"
    unsecureActor ! "10"

    Thread.sleep(10000)
  }
}

class UnsecureActor extends Actor {
  def methodWithThread(): Unit = {
  }

  override def receive: Receive = {
    case msg: String =>
      var t = new ThreadExample(msg)
      // by starting a new thread inside an Akka actor you break the synchronous pattern provided by Akka
      t.start()
  }
}

class ThreadExample(id: String) extends Thread {
  override def run() {
    // simulate a random computation which will potentially break the order of messages processed by Akka actors
    // This is where the Akka actors don't have control anymore.
    Thread.sleep(Random.nextInt(10) * 1000)
    println(s"finished $id");
  }
}

输出的顺序与 unsecureActor ! "1" 发送消息的顺序不同。

finished 9
finished 4
finished 1
finished 7
finished 3
finished 2
finished 8
finished 5
finished 6
finished 10

可以在 Actor 内部的单独线程中启动代码(例如使用 Future),但您必须注意它与 Akka 的交互方式。线程不应该读取或修改 Actor 中的任何可变状态,它应该只通过发送消息与 Actor 通信。