Home/Learn/Operating Systems/Multithreading Models

Multithreading Models

Intermediate
Processes & Threads

The three multithreading models — Many-to-One, One-to-One, and Many-to-Many — define how user-level threads map to kernel threads, determining parallelism capability and scheduling flexibility.

Overview

An OS must decide how to map the threads a programmer creates (user threads) onto the threads it actually schedules on the CPU (kernel threads). Many-to-One maps all user threads to a single kernel thread — simple but no parallelism and one block stalls all. One-to-One gives each user thread its own kernel thread — true parallelism but unlimited thread creation is expensive; this is the model used by Linux pthreads, Windows, and standard Java. Many-to-Many (or Two-Level) multiplexes M user threads onto N kernel threads where N ≤ M — combines flexibility with performance; used by Go goroutines and Java 21 virtual threads. Choosing the right model affects throughput, latency, and resource consumption.

One-to-One Model: Standard Java Threads

Linux and Windows both implement the one-to-one model — each java.lang.Thread (platform thread) corresponds to exactly one OS kernel thread. This allows true parallelism: threads run simultaneously on different CPU cores. The downside is cost — each thread consumes about 1 MB of stack memory by default, so creating 100,000 threads would exhaust memory.

Java — One-to-One model with thread pool
// One-to-One: each Thread = one OS kernel thread
// Default stack size ~512KB–1MB per thread
ExecutorService pool = Executors.newFixedThreadPool(
    Runtime.getRuntime().availableProcessors() // match CPU cores for CPU-bound
);

List<Future<Integer>> results = new ArrayList<>();
for (int i = 0; i < 100; i++) {
    int task = i;
    results.add(pool.submit(() -> {
        // Each task runs on a kernel thread from the pool
        return task * task;
    }));
}
for (Future<Integer> f : results) System.out.println(f.get());
pool.shutdown();

// Check active thread count
System.out.println("Active threads: " + Thread.activeCount());

Many-to-Many Model: Virtual Threads (Java 21)

Java 21 virtual threads implement Many-to-Many: millions of virtual (user) threads multiplexed onto a small pool of carrier (kernel) threads. When a virtual thread blocks on I/O, it is unmounted from its carrier thread, which then picks up another virtual thread. This allows writing simple sequential code that scales like non-blocking async code.

Java 21 — Many-to-Many with virtual threads for I/O tasks
// Many-to-Many: millions of virtual threads on N carrier threads
// N ≈ Runtime.getRuntime().availableProcessors() by default

// I/O-bound workload — perfect for virtual threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    // Simulate 10,000 concurrent HTTP calls (each blocks on network I/O)
    var futures = IntStream.range(0, 10_000)
        .mapToObj(i -> executor.submit(() -> {
            // simulatedHttpCall() blocks — virtual thread parks, carrier is freed
            Thread.sleep(50);  // simulates network latency
            return "response-" + i;
        }))
        .toList();

    long done = futures.stream().filter(f -> {
        try { f.get(); return true; } catch (Exception e) { return false; }
    }).count();
    System.out.println("Completed: " + done);
}

Key Points to Remember

  • 1Many-to-One: all user threads share one kernel thread — no parallelism, rarely used today.
  • 2One-to-One: each user thread = one kernel thread — true parallelism; used by Linux, Windows, and standard Java.
  • 3Many-to-Many: M user threads on N kernel threads — flexible and efficient; used by Go and Java 21 virtual threads.
  • 4Platform threads (one-to-one) are best for CPU-bound tasks equal to core count.
  • 5Virtual threads (many-to-many) are best for I/O-bound tasks where threads spend most time waiting.
  • 6Java virtual threads are not pooled — the JVM carrier pool handles multiplexing automatically.

Interview Questions

Sign in to ask Aria
1

Explain the three multithreading models and their trade-offs.

MediumGoogle
2

Why does the one-to-one model limit the number of threads you can practically create?

EasyAmazon
3

How does the Many-to-Many model avoid the "one blocking call blocks all" problem?

HardMicrosoft
4

Which threading model does Go use for goroutines?

MediumUber

Ask Aria about Multithreading Models

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…