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.
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