Home/Learn/Operating Systems/Concurrency vs Parallelism

Concurrency vs Parallelism

Beginner
Processes & Threads

Concurrency is about dealing with multiple tasks at once by interleaving progress; parallelism is about doing multiple tasks simultaneously using multiple CPU cores.

Overview

Concurrency and parallelism are related but distinct concepts. Concurrency means the system is managing multiple tasks — they make progress, but not necessarily at the exact same instant. On a single core, a scheduler rapidly switches between tasks, giving the illusion of simultaneity. Parallelism means tasks are literally executing at the same time on different hardware (CPU cores, GPUs). You can have concurrency without parallelism (time-sliced multitasking on one core), and you can have parallelism only with concurrency. Rob Pike's aphorism: "Concurrency is about structure; parallelism is about execution." Java supports concurrency via threads, and parallelism via parallel streams and ForkJoinPool on multi-core machines.

Concurrency: Interleaving on a Single Core

Concurrency is the composition of independently executing things. A single-core CPU running multiple threads is concurrent but not parallel — the OS rapidly context-switches between threads. This is valuable for I/O-bound tasks: while one thread waits for a database response, another thread can do useful work. A restaurant analogy: one waiter serves multiple tables concurrently by interleaving attention, not by cloning themselves.

Java — concurrent tasks on a single-threaded executor
// Concurrency on a single core — tasks interleave
// This is concurrent even if availableProcessors() == 1

ExecutorService single = Executors.newSingleThreadExecutor();

Runnable taskA = () -> {
    System.out.println("Task A started on: " + Thread.currentThread().getName());
    try { Thread.sleep(100); } catch (InterruptedException e) {}
    System.out.println("Task A done");
};
Runnable taskB = () -> {
    System.out.println("Task B started on: " + Thread.currentThread().getName());
    try { Thread.sleep(100); } catch (InterruptedException e) {}
    System.out.println("Task B done");
};

// Both submitted — executed concurrently in structure, sequentially on 1 thread
single.submit(taskA);
single.submit(taskB);
single.shutdown();

// Available processors — determines parallelism potential
System.out.println("Cores: " + Runtime.getRuntime().availableProcessors());

Parallelism: Simultaneous Execution on Multiple Cores

Parallelism requires multiple CPU cores. Java parallel streams split data across worker threads in ForkJoinPool.commonPool(), which has parallelism level equal to availableProcessors()-1. Parallel streams are ideal for CPU-bound operations on large datasets. For I/O-bound work, concurrency (many threads) scales better than parallelism (few threads equal to cores).

Java — sequential vs parallel stream, measuring speedup
int cores = Runtime.getRuntime().availableProcessors();
System.out.println("Available cores: " + cores);

List<Integer> numbers = IntStream.rangeClosed(1, 10_000_000)
    .boxed().collect(Collectors.toList());

// Sequential stream — single thread, concurrent at OS level
long start = System.nanoTime();
long sumSeq = numbers.stream()
    .mapToLong(Integer::longValue).sum();
long seqTime = System.nanoTime() - start;

// Parallel stream — uses ForkJoinPool, executes on multiple cores simultaneously
start = System.nanoTime();
long sumPar = numbers.parallelStream()
    .mapToLong(Integer::longValue).sum();
long parTime = System.nanoTime() - start;

System.out.printf("Sequential: %d ms%n", seqTime / 1_000_000);
System.out.printf("Parallel:   %d ms  (speedup: %.1fx)%n",
    parTime / 1_000_000, (double) seqTime / parTime);

// Custom ForkJoinPool to control parallelism
ForkJoinPool customPool = new ForkJoinPool(4); // limit to 4 threads
long result = customPool.submit(() ->
    numbers.parallelStream().mapToLong(Integer::longValue).sum()
).get();

Key Points to Remember

  • 1Concurrency: multiple tasks making progress via interleaving — possible on a single core.
  • 2Parallelism: multiple tasks executing simultaneously — requires multiple CPU cores.
  • 3I/O-bound workloads benefit from concurrency (many threads); CPU-bound from parallelism (threads = cores).
  • 4Java parallel streams use ForkJoinPool.commonPool() with parallelism = availableProcessors() - 1.
  • 5Concurrency introduces race conditions; parallelism amplifies them — both require synchronization.
  • 6Virtual threads maximize concurrency for I/O-bound tasks without increasing parallelism.

Interview Questions

Sign in to ask Aria
1

What is the difference between concurrency and parallelism?

EasyAmazon
2

Can you have concurrency without parallelism? Give an example.

EasyFlipkart
3

When would you prefer parallel streams over virtual threads?

MediumGoogle
4

Why does a parallel stream not always run faster than a sequential stream?

MediumAdobe

Ask Aria about Concurrency vs Parallelism

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…