Concurrent and Actor Programming
The Problem: Shared Mutable State
The traditional model is threads sharing memory, protected by locks. It is fast, but two threads updating the same value can interleave and corrupt it (a race condition), and locks can wait on each other forever (a deadlock). These bugs depend on timing, so they are rare in tests and common in production.
Message Passing and the Actor Model
The alternative is to give up sharing. Each activity owns its data privately and communicates only by sending messages. In the actor model (Hewitt, 1973) an actor can do exactly three things when it receives a message: send messages to other actors, create new actors, and decide how it will behave for the next message.
- Isolation — no other actor can touch an actor's state, so it needs no locks.
- Mailboxes — messages queue up and are handled one at a time.
- Location transparency — sending a message looks the same whether the receiver is local or on another machine.
- Supervision — when an actor fails, another actor restarts it. The Erlang motto is "let it crash".
CSP: Communicating Sequential Processes
Tony Hoare's CSP (1978) is a close relative. Instead of addressing an actor, processes communicate through named channels: one process sends a value on a channel and another receives it. On an unbuffered channel the send and the receive meet, so channels synchronize as well as transfer data. Go's goroutines and channels are the best-known modern form.
Both models share the slogan "do not communicate by sharing memory; share memory by communicating".
Other Tools You Will Meet
- Threads and locks — the low-level model of Java, C++ and C#, still needed for shared caches and performance-critical code.
- async/await — cooperative concurrency in one thread for waiting on I/O (JavaScript, Python, Rust, C#).
- Software transactional memory — shared memory with atomic transactions, as in Haskell and Clojure.
- Ownership and capabilities — type systems such as Rust's and Pony's that reject data races at compile time.
Representative Languages
These four languages show the two big families: actors (Erlang, Elixir, Pony) and CSP (Go).
| Language | Why study it |
|---|---|
| Erlang | The origin of practical actors: millions of lightweight processes, supervision and hot code loading. |
| Elixir | Actors on the same virtual machine with a modern syntax, macros and the Phoenix web framework. |
| Go | CSP with goroutines and channels in a small, fast, compiled language. |
| Pony | Actors with reference capabilities so that the compiler proves the absence of data races. |