You get both. It’s possible to have lightweight threads (fibers/coroutines/green threads etc.) with libraries like core.async and limit yourself to a single os thread (or the only thread you have, in the case of clojurescript in the browser). Or you can multiplex them over a threadpool of OS threads, or mix-and-match. This is the approach clojure core.async takes (go routines are multiplexed over a user-configurable threadpool, and you can spawn dedicated threads as well).
You can also use existing java abstractions for OS threads, leverage fork/join, etc. clojure wraps os thread creation via future
and leverages a threadpool for handling agent
async processing. Clojure reducers (specifically fold
) leverage the fork/join implementation underneath.