multithreadingscalaconcurrencyakkaakka-actor

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


Let's assume I have an actor class with a method in Akka Actor:

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

Can a run a new thread in this method? Wouldn't it be problematic regarding Akka's own threading?

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

Solution

  • Since you said that you are looking for how to make sure that this way that you want to create async tasks from an Akka Actor will break the Akka concurrency pattern that it provides to you, here is some very simple example based on your classes.

    This is not an answer to demonstrate how to spawn child actors from a parent actor as I suggested in my commentary. And as you also said that you are interested to demonstrate how to break the Akka concurrency pattern. I suggested that you look for simple examples of how to do that. Maybe this example helps.

    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");
      }
    }
    

    the output will be in a different order than the unsecureActor ! "1" send messages.

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