Futures, Promises, Delays and Virtual Threads

Libraries: claypoole (thread pools with pmap variants), manifold (deferreds and streams), promesa (promises, also on JVM virtual threads).

;; future: run on another thread, deref blocks for the result
(def f (future (Thread/sleep 500) (* 6 7)))
(realized? f)                            ; false (initially)
@f                                       ; 42 (blocks until done)
(deref f 100 :timeout)                   ; deref with a timeout and a default
(future-cancel f) (future-done? f)

;; Parallel calls
(let [a (future (fetch-user 1))
      b (future (fetch-orders 1))]
  {:user @a :orders @b})

(pmap #(do (Thread/sleep 100) (* % %)) (range 8))   ; parallel map (for CPU-heavy, coarse tasks)

;; promise: a one-time value delivered by someone else
(def p (promise))
(future (Thread/sleep 100) (deliver p :done))
@p                                       ; :done

;; delay: compute once, on first deref (lazy, thread-safe)
(def config (delay (println "loading config...") {:port 8080}))
@config                                  ; prints once, returns the map
@config                                  ; cached

;; locking: Java monitor
(def lock (Object.))
(locking lock (println "critical section"))

;; Java interop: executors and virtual threads (JDK 21+)
(import '(java.util.concurrent Executors))
(with-open [exec (Executors/newVirtual
…