Part 5 · 1 chapters · ~8 min

Concurrency Models

Concurrency versus parallelism, threads and locks, event loops and async/await (colored functions), CSP with goroutines and channels, actors and supervision trees, virtual threads and structured concurrency, software transactional memory (Clojure, Haskell), data parallelism, and choosing a language by its concurrency model.

6

Five languages, one fan-out

code
// Node: async, one thread
const results = await Promise.all(ids.map(id => fetchBalance(id)));

// Go: goroutines and a channel
ch := make(chan Balance, len(ids))
for _, id := range ids { go func(id string) { ch <- fetchBalance(id) }(id) }
for range ids { results = append(results, <-ch) }

// Java 21: virtual threads with blocking calls
try (var ex = Executors.newVirtualThreadPerTaskExecutor()) {
  var futures = ids.stream().map(id -> ex.submit(() -> fetchBalance(id))).toList();
  for (var f : futures) results.add(f.get());
}

# Elixir: isolated processes, results as messages
results = ids |> Task.async_stream(&fetch_balance/1, max_concurrency: 50) |> Enum.map(fn {:ok, b} -> b end)

// Rust: async with tokio
let results = futures::future::join_all(ids.iter().map(|id| fetch_balance(id))).await;

Coloured functions: in async/await languages, async functions can only be awaited from other async functions, splitting the ecosystem in two. Go, Java virtual threads and Erlang avoid the split by making blocking cheap.

CONCURRENCY MODELS AND THEIR LANGUAGES
one problem, five answers
threads + locksJava, C++, Python: shared memoryguarded by mutexes.event loop + asyncNode, Python asyncio, Rust tokio:one thread, many waiting tasks.CSP: goroutines + channelsGo: cheap tasks that share bycommunicating.actorsErlang, Elixir, Akka: isolatedprocesses with mailboxes,supervisors.virtual threadsJava 21: blocking code style,millions of lightweight threads.data parallelismRayon, NumPy, GPUs: same operationover many elements.
swipe the figure sideways, or tap expand for full screen
1/5
threads and locks
The default in most languages and the source of most concurrency bugs: races and deadlocks (Concurrency course).
shared memory + locksraces and deadlocks