Introduction With the advent of multi-core processors concurrent programming is becoming indispensable. Scala's primary concurrency construct is actors. Actors are basically concurrent processes that communicate by exchanging messages. Actors can also be seen as a form of active objects where invoking a method corresponds to sending a message. The Scala Actors library provides both asynchronous and synchronous message sends (the latter are implemented by exchanging several asynchronous messages). Moreover, actors may communicate using futures where requests are handled asynchronously, but return a representation (the future) that allows to await the reply. This tutorial is mainly designed as a walk-through of several complete example programs that can be readily compiled and run using Scala 2.4 or newer.

First Example Our first example consists of two actors that exchange a bunch of messages and then terminate. The first actor sends "ping" messages to the second actor, which in turn sends "pong" messages back (for each received "ping" message one "pong" message). We start off by defining the messages that are sent and received by our actors. In this case, we can use singleton objects (in more advanced programs, messages are usually parameterized). Since we want to use pattern matching, each message is a case object : case object Ping case object Pong case object Stop The ping actor starts the message exchange by sending a Ping message to the pong actor. The Pong message is the response from the pong actor. When the ping actor has sent a certain number of Ping messages, it sends a Stop message to the pong actor. All classes, objects and traits of the Scala actors library reside in the scala.actors package. From this package we import the Actor class that we are going to extend to define our custom actors. Furthermore, we import all members of the Actor object since it contains many useful actor operations: import scala.actors.Actor import scala.actors.Actor._ Actors are normal objects that are created by instantiating subclasses of the Actor class. We define the behavior of ping actors by subclassing Actor and implementing its abstract act method: class Ping(count: int, pong: Actor) extends Actor { def act() { var pingsLeft = count - 1 pong ! Ping while (true) { receive { case Pong => if (pingsLeft % 1000 == 0) Console.println("Ping: pong") if (pingsLeft > 0) { pong ! Ping pingsLeft -= 1 } else { Console.println("Ping: stop") pong ! Stop exit() } } } } } The number of Ping messages to be sent and the pong actor are passed as arguments to the constructor. The call to the receive method inside the infinite loop suspends the actor until a Pong message is sent to the actor. In that case the message is removed from the actor's mailbox and the corresponding action on the right side of the arrow is executed. In the case where pingsLeft is greater than zero we send a Ping message to pong using the send operator ! , and decrement the pingsLeft counter. If the pingsLeft counter has reached zero, we send a Stop message to pong , and terminate the execution of the current actor by calling exit() . The class for our pong actor is defined similarly: class Pong extends Actor { def act() { var pongCount = 0 while (true) { receive { case Ping => if (pongCount % 1000 == 0) Console.println("Pong: ping "+pongCount) sender ! Pong pongCount = pongCount + 1 case Stop => Console.println("Pong: stop") exit() } } } } There is one interesting point to notice, however. When receiving a Ping message, a Pong message is sent to the sender actor, which is not defined anywhere in our class! In fact, it is a method of the Actor class. Using sender , one can refer to the actor that sent the message that the current actor last received. This avoids having to explicitly pass the sender as arguments to messages. After having defined our actor classes, we are now ready to create a Scala application that uses them: object pingpong extends Application { val pong = new Pong val ping = new Ping(100000, pong) ping.start pong.start } Analogous to Java threads, actors have to be started by calling their start method. Let's run it! The complete example is included in the Scala distribution under doc/scala-devel/scala/examples/actors/pingpong.scala . Here is how you compile and run it: $ scalac pingpong.scala $ scala -cp . examples.actors.pingpong Pong: ping 0 Ping: pong Pong: ping 1000 Ping: pong Pong: ping 2000 ... Ping: stop Pong: stop

Make it Thread-less! Actors are executed on a thread pool. Initially, there are 4 worker threads. The thread pool grows if all worker threads are blocked but there are still remaining tasks to be processed. Ideally, the size of the thread pool corresponds to the number of processor cores of the machine. When actors call thread-blocking operations, such as receive (or even wait ), the worker thread that is executing the current actor ( self ) is blocked. This means basically that the actor is represented as a blocked thread. Depending on the number of actors you want to use, you might want to avoid this, since most JVMs cannot handle more than a few thousand threads on standard hardware. Thread-blocking operations can be avoided by using react to wait for new messages (the event-based pendant of receive ). However, there is a (usually small) price to pay: react never returns. In practice, this means that at the end of a reaction to a message, one has to call some function that contains the rest of the actor's computation. Note that using react inside a while loop does not work! However, since loops are common there is special library support for it in form of a loop function. It can be used like this: loop { react { case A => ... case B => ... } } Note that react calls can be nested. This allows to receive several messages in sequence, like this: react { case A => ... case B => react { // if we get a B we also want a C case C => ... } } To make our ping and pong actors thread-less, it suffices to simply replace while (true) with loop , and receive with react . For example, here is the modified act method of our pong actor: def act() { var pongCount = 0 loop { react { case Ping => if (pongCount % 1000 == 0) Console.println("Pong: ping "+pongCount) sender ! Pong pongCount = pongCount + 1 case Stop => Console.println("Pong: stop") exit() } } }