Concurrency
- In Turkish
- Eşzamanlılık
- Pronunciation
- kun-KUR-un-see
In short
Concurrency is a program's ability to make progress on several tasks in overlapping time periods, such as serving many users at once rather than one at a time.
What is concurrency in programming?
Concurrency means structuring a program so it can deal with multiple tasks at once, switching between them as needed instead of finishing one completely before starting the next. A web server handling thousands of users, a browser downloading files while you scroll, and a phone app loading images in the background all rely on concurrency. It is especially useful when tasks spend time waiting, for example on a network response or a disk read.
There are several ways to achieve concurrency. Threads let the operating system run separate sequences of instructions within one program, while event loops, used by JavaScript and Node.js, run one piece of code at a time on a single thread but switch to other work whenever a task is waiting on input/output. Languages also offer higher-level tools such as async/await, goroutines in Go, and actors in Erlang and Elixir.
A single chef cooking several dishes is a classic analogy for concurrency: while the pasta boils, the chef chops vegetables, then stirs the sauce, keeping every dish moving. Parallelism is like having several chefs, each cooking a dish at the same moment, just as multiple CPU cores run code simultaneously. Concurrency is about dealing with many things at once, while parallelism is about doing many things at once, and a program can be concurrent without being parallel.
Concurrency brings its own class of bugs. A race condition happens when the result depends on the unpredictable timing of tasks, such as two threads updating the same bank balance at once and one update being lost. Developers prevent these with locks, atomic operations, message passing, or immutable data, but careless locking can cause a deadlock, where two tasks wait on each other forever.
At a glance
Key takeaways
- Concurrency lets a program make progress on multiple tasks in overlapping time periods.
- It can be achieved with threads, event loops, async/await, goroutines, or actors.
- Parallelism means tasks run at literally the same time on multiple cores; concurrency does not require it.
- Shared mutable data can cause race conditions and deadlocks if access isn't coordinated.
Example
// Concurrent: both requests are in flight at the same time
async function loadDashboard() {
const [user, orders] = await Promise.all([
fetch("/api/user").then((res) => res.json()),
fetch("/api/orders").then((res) => res.json()),
]);
return { user, orders };
}
// Sequential: the second request waits for the first to finish
async function loadDashboardSlowly() {
const user = await fetch("/api/user").then((res) => res.json());
const orders = await fetch("/api/orders").then((res) => res.json());
return { user, orders };
}Readers ask
What is the difference between concurrency and parallelism?
Concurrency is about managing multiple tasks whose lifetimes overlap, even if only one runs at any given instant. Parallelism is about executing multiple tasks at literally the same time on multiple CPU cores; it is one way to run concurrent work, but not the only one.
What is a race condition?
A race condition is a bug where the outcome depends on the timing or order in which concurrent tasks run. For example, if two tasks read a counter, add one, and write it back at the same time, one of the increments can be lost.
Is JavaScript concurrent?
Yes. JavaScript runs your code on a single thread, but its event loop lets it handle many operations concurrently, such as timers and network requests, by running other code while it waits. For true parallelism, browsers offer Web Workers and Node.js offers worker threads.
Often compared
See also
- Async/AwaitProgramming Fundamentals, p. 4Async/await is a syntax for writing asynchronous code that reads like ordinary step-by-step code, pausing at each await until a promise or task finishes.
- PromiseProgramming Fundamentals, p. 46A promise is an object that represents the eventual result of an asynchronous operation, letting code react to success or failure once the work completes.
- CallbackProgramming Fundamentals, p. 7A callback is a function passed as an argument to another function, which then calls it later, for example when a task finishes or an event happens.
- Functional ProgrammingProgramming Fundamentals, p. 22Functional programming is a style of building software from pure functions that avoid changing shared data, making code more predictable and easier to test.
- Node.jsBackend & APIs, p. 32Node.js is an open-source JavaScript runtime that runs JavaScript outside the browser, most often to build web servers, APIs, and command-line tools.
- Message QueueBackend & APIs, p. 29A message queue is a component that stores messages from one service until another is ready to process them, so parts of a system can work asynchronously.
- ParallelismProgramming Fundamentals, p. 42Parallelism is running several computations at literally the same time, on multiple CPU cores, GPUs or machines, so a large job finishes faster.
- GoProgramming Languages, p. 13Go is a compiled, statically typed language built for simplicity and fast builds, with garbage collection and built-in concurrency through goroutines.
Spotted a mistake or something missing on this page?Suggest an edit