← Concepts

阅读中文版本

Green Threads

Green threads are user-space scheduled threads multiplexed over few OS threads, enabling lightweight concurrency — millions of tasks — but requiring cooperative yields and runtime-owned I/O.

concurrency

Definition

Green threads are scheduled entirely in user space by the runtime or library, not the kernel. Creation is an allocation, not a syscall; context switch is a function call, not a trap. The runtime multiplexes many green threads onto a small pool of OS threads. Blocking kernel operations must be avoided or intercepted, since a blocking green thread pins its carrier.

Context and scope

Go goroutines, Erlang processes, early Java green threads, and Windows fibers. The modern JVM answer is virtual threads; async/await is the callback-shaped alternative to the same problem.

Common misconceptions

  • Green threads use all cores — a single-threaded green thread scheduler pins to one core unless the runtime multiplexes onto a thread pool
  • Blocking calls work as usual — blocking OS calls freeze the carrier thread and stall every green thread multiplexed on it
  • Green threads remove the need for synchronization — shared memory races exist exactly as with OS threads

Anti-patterns

  • Calling blocking JDBC or file APIs from goroutine-heavy services and starving the scheduler
  • Assuming green thread counts scale linearly with no memory accounting for stacks
  • Mixing green thread schedulers with thread-affine native libraries and deadlocking the runtime

Related concepts

Related examples

Authoritative source

https://en.wikipedia.org/wiki/Green_thread

What it is

OS threads cost megabytes of stack and a kernel scheduling object each; you can afford thousands, not millions. Green threads shrink both costs into user space: small or growable stacks, and a scheduler that switches contexts in nanoseconds.

How it works

The runtime scheduler maintains runnable queues and multiplexes M green threads onto N OS threads. Yield points are explicit cooperative calls or compiler-inserted checks at function boundaries. I/O must route through runtime-aware non-blocking interfaces so the scheduler parks the green thread, not the carrier.

When to use it

Massive concurrency with blocking-style code readability: many open connections, per-session state machines, pipelines. The runtime owns I/O, which is the price of transparent suspension.

Pitfalls

Blocking into kernel space — a blocking library call pins the carrier and every multiplexed task with it. Preemption granularity varies: Go preempts at function entries and loop backedges; older runtimes never preempt, letting one busy task starve all others. Stack accounting and scheduler tuning become operational work at scale.