Fundamentals 20 min read

Understanding Concurrency: Threads, Goroutine, Actor Model, and Thread‑Pool Strategies

This article explores the fundamentals of concurrency versus parallelism, the challenges of writing correct concurrent programs, the evolution from OS threads to green threads, Goroutine scheduling, actor‑model concepts, and modern strategies such as thread pools, async callbacks, and Rust's ownership model.

High Availability Architecture
High Availability Architecture
High Availability Architecture
Understanding Concurrency: Threads, Goroutine, Actor Model, and Thread‑Pool Strategies

The article begins by distinguishing concurrency (task slicing) from parallelism (simultaneous execution) and explains why many developers find concurrent programming difficult, often due to using inappropriate tools and abstractions.

It reviews the historical evolution from procedural and object‑oriented code to the introduction of OS threads, describing threads as lightweight processes scheduled by the kernel, sharing resources within a process, and highlighting their role in GUI responsiveness and handling multiple users.

Key challenges of thread‑based concurrency are discussed, including race conditions, dependency ordering, and the overhead of synchronization primitives such as mutexes, semaphores, volatile, and compare‑and‑swap.

The article then examines the cost of threads—memory consumption for stacks and context‑switch overhead—and shows how these costs influence decisions about the optimal number of threads, using simple calculations and analogies.

Thread‑pool solutions (e.g., Java’s Executor framework) are introduced as a way to limit thread creation and enable reuse, though they still require careful sizing and may lead to many pools in complex systems.

Two modern approaches are presented: asynchronous callbacks (as in Node.js) and green‑thread/coroutine/fiber models that keep execution in user space, allowing massive numbers of lightweight tasks with smaller stacks.

The Goroutine model in Go is detailed, covering its built‑in coroutine mechanism, scheduler, and channel‑based communication that implements the CSP model, along with a description of the M‑P‑G scheduling architecture.

Limitations of Goroutine‑only solutions are noted, especially when other resources (locks, DB connections) become bottlenecks, prompting the need for Goroutine pools and flow control.

The actor model is introduced, contrasting it with object‑oriented design and explaining its core properties (processing, storage, communication) and rules (send messages, create actors, handle messages).

Differences between CSP (Go) and actor models are compared, emphasizing message‑centric versus channel‑centric designs, synchronization semantics, and suitability for different architectural patterns.

Rust’s approach to concurrency is discussed, focusing on ownership and compile‑time guarantees that prevent data races, offering an alternative to runtime‑only checks.

Finally, the article concludes that while many tools reduce the difficulty of concurrent programming, the problem is not fully solved and further research into self‑managing, distributed, and container‑integrated systems is needed.

Concurrencyprogrammingthread poolgoroutineParallelismThreadsactor-model
High Availability Architecture
Written by

High Availability Architecture

Official account for High Availability Architecture.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.