Browse Clojure Foundations for Java Developers

Futures and Promises

Simple async tools on the JVM: futures run a computation; promises are one-time values you deliver later (both deref with @).

Futures and promises are the simplest async building blocks you’ll see in Clojure codebases. Both are derefable, so @x blocks until a value is available (or returns immediately if realized).

Futures: Run a Computation Asynchronously

1(def f (future
2         (Thread/sleep 100)
3         42))
4
5(realized? f) ; => false (usually)
6@f            ; blocks, then => 42

If you need it, Clojure also provides:

  • future-cancel, future-cancelled?, future-done?

Promises: A One-Time Value Delivered Later

1(def p (promise))
2
3(future (deliver p 42))
4
5@p ; blocks until delivered => 42

You can avoid blocking forever with a timeout:

1(deref p 1000 :timeout) ; => 42 (or :timeout if not delivered in time)

Knowledge Check: Futures and Promises

### What does dereferencing a future (like `@f`) do? - [x] Blocks until the computation finishes, then returns its result (or throws its exception). - [ ] Cancels the future. - [ ] Forces the future to run on the current thread. - [ ] Returns `nil` until the future completes. > **Explanation:** Futures are derefable. Deref blocks until a result is ready. ### What does `deliver` do for a promise? - [x] Completes the promise with a value (one-time), unblocking deref. - [ ] Starts a new thread pool. - [ ] Retries a promise computation under contention. - [ ] Converts a promise into a future. > **Explanation:** A promise is a placeholder. `deliver` sets its value once. ### How can you avoid blocking forever on a promise? - [x] Use `(deref p timeout-ms timeout-val)` (or check `realized?`). - [ ] Use `swap!` on the promise. - [ ] Use `dosync`. - [ ] Use `conj`. > **Explanation:** `deref` supports a timeout and default value. `realized?` can tell you whether a derefable has a value already.
Revised on Friday, April 24, 2026