Browse Clojure Foundations for Java Developers

core.async and Channels

Build readable async pipelines with channels, go blocks, and explicit backpressure.

core.async gives you CSP-style channels: a channel is a queue-like coordination primitive, and you compose your program as small stages that put values onto channels and take values off channels.

Inside a go block, channel operations park rather than blocking an OS thread, which makes it practical to express a lot of waiting without a lot of threads.

1(require '[clojure.core.async :as a])
2
3(let [ch (a/chan 10)]
4  (a/go (a/>! ch {:event :ping}))
5  (a/go (println (a/<! ch))))

Java mental model: a channel can feel like BlockingQueue, but the important difference is “parking vs blocking” and the need to keep blocking I/O out of go.

In this section

Revised on Friday, April 24, 2026