DEV Community

Teiva Harsanyi for The Coder Cafe

Posted on

Concurrency vs. Parallelism

Image description

It’s fairly common for developers to mix up the concepts of concurrency and parallelism, but they are actually quite distinct. Let’s approach these two concepts using a coffee shop analogy.

Imagine a coffee shop with one waiter who takes orders and makes coffee using a single machine. Customers wait in line, place their orders, and then wait for their coffee:

Image description

If the waiter struggles to keep up with the number of customers, the coffee shop owner may decide to speed up the overall process by engaging a second waiter and buying a second coffee machine. Now, two waiters can serve customers at the same time:

Image description

In this setup, the two waiters work independently. Each has its own coffee machine, allowing the shop to serve customers twice as fast. This is parallelism—executing multiple tasks simultaneously by adding more resources (waiters and machines).

If we want to scale further, we can keep adding more waiters and machines, but this approach has its limits. For example, buying multiple coffee machines can become overly expensive.

Instead of just adding more machines, we could rethink how the work is structured. One way to do this is by splitting the tasks between the waiters: one takes orders, and the other makes coffee using a coffee machine. To avoid blocking the customer queue, we introduce a second queue where customers wait for their coffee (similar to Starbucks):

Image description

Here, what we have changed is the overall structure; this is concurrency. The tasks are structured to be handled independently, even if they don’t happen at the same time.

Now, imagine each thread in an application represents a role: one thread for taking orders and another for making coffee. These threads work independently but must coordinate. For example, the ordering threads need to pass information about what to prepare to the coffee-making thread.

What if we want to increase the shop’s capacity further? Since making coffee takes longer than taking orders, we could hire another waiter specifically to make coffee:

Image description

Has the structure been changed? No. It’s still a three-step design:

  1. Accept orders

  2. Make coffee

  3. Serve coffee

However, by adding another waiter just for coffee-making, we introduce parallelism into this specific step without altering the overall concurrency structure.

Remember that while parallelism and concurrency are distinct, they can complement each other. Parallelism can exist without concurrency, but concurrency can enable parallelism as it provides a structure to solve a problem with parts that may be parallelized.

To summarize:

  • Concurrency is about structure, and we design a solution so that parts can be managed independently. This doesn’t necessarily mean they run at the same time but rather that they are organized in a way that allows for more efficient execution.

  • Parallelism is about execution, performing multiple tasks simultaneously by adding more threads.

Tomorrow, we will keep exploring the concepts of concurrency and parallelism by discussing coroutines.


This post is from The Coder Cafe newsletter.

Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders daily. Written by a software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.

Image description

Top comments (0)