Java comes with a built-in multi-threading model based on shared data and locks. To use this model, you decide what data will be shared by multiple threads and mark as “synchronized” sections of the code that access the shared data.

It also provides a locking mechanism to ensure that only one thread can access the shared data at a time. Lock operations remove possibilities for race conditions but simultaneously add possibilities for deadlocks. In Scala, you can still use Java threads, but the “Actor model” is the preferred approach for concurrency.

Actors provide a concurrency model that is easier to work with and can, therefore, help you avoid many of the difficulties of using Java’s native concurrency model.

Features of Actors

  1. When you instantiate an Actor in your code, Akka gives you an ActorRef, which you can use to send messages.
  2. Behind the scenes, Akka runs actors on real threads and many actors may share one thread.
  3. A Actor can create many actors called child actors.
  4. Actors interact only through asynchronous messages and never through direct method calls.
  5. Each actor has a unique address and a mailbox in which other actors can deliver messages.
  6. The actor will process all the messages in the mailbox in sequential order  (the implementation of the mailbox is FIFO).

Let’s see an example,

  case class Add(num1: Int, num2: Int)
  case class Substract(num1: Int, num2: Int)
  case class Divide(num1: Int, num2: Int)

  class Calculator extends Actor {

    def receive = {
      case Add(num1, num2) => context.actorOf(Props[Addition]) ! Add(num1, num2)
      case Substract(num1, num2) => context.actorOf(Props[Substraction]) ! Substract(num1, num2)
      case Divide(num1, num2) => context.actorOf(Props[Division]) ! Divide(num1, num2)
    }
  }

  class Addition extends Actor {
    def receive = {
      case Add(num1, num2) => println(num1 + num2)
    }
  }

  class Substraction extends Actor {
    def receive = {
      case Substract(num1, num2) => println(num1 - num2)
    }
  }

  class Division extends Actor {
    def receive = {
      case Divide(num1, num2) => println(num1 % num2)
    }
  }

The output of this is as follows,

Started Calculating.....
Addition
Substraction
Divide
5
1
2

If you observe the output, main actor sends all three messages to the actor Calculator (parent actor) at the same time and all three operations performed asynchronously.

#scala #actors #akka #concurrency #scala

Achieving Concurrency with Akka Actors
2.35 GEEK