The Actor model can be used to isolate mutable state from the outside world. When you have a mutable state (for example a global registry of IDs assigned to multiple concurrent processes), you can wrap that mutable state up inside an Actor and make the clients communicate with the Actor via message-passing. That way only the actor accesses the mutable state directly, and as you say, the client messages queue up to be read and processed one-by-one. It is important for messages to be immutable.
To avoid the queue getting full, it is important that the message processing (react
, receive
, etc.) be as short as possible. Long-running tasks should be handed off to an other actor:
1. Actor A receives a message M from sender S
2. A spawns a new actor C
3. A sends (S, f(M)) to C
4. In parallel:
4a. A starts processing the next message.
4b. C does the long-running or dangerous (IO) task,
When finished, sends the result to S,
and C terminates.
Some alternatives in the process:
- C sends
(S, result)
back to A who forwards to S
- A keeps a mapping
ActorRef C => (Sender S, Message M)
so in case it sees C fail, it can retry processing M with a new Actor.
So to recap, an Actor is multi-threaded to the extent that multiple clients can send it multiple messages from various threads, and it is guaranteed that the Actor will process all these messages serially (although the ordering can be subject to various non-overly strict constraints).
Note that while the Actor's react
code may be executed on various threads, in a single given point of time it is executed on a single given thread only (you can picture this that the Actor jumps from thread to thread as the scheduler sees fit, but this is a technical detail). Note: The internal state still doesn't need syncronization, since Actors guarantee happens-before semantics between processing messages.
Parallelism is achieved by having multiple Actors working in parallel, usually forming supervisor hierarchies or balancing workload.
Note that if all you need is concurrent/asynchronous computations, but you don't have or can get rid of global state, Future
s are a better composing and easier concept.