Thread Pools, Executors & Futures
Stop creating threads by hand
Threads are expensive to create (an OS call, ~1 MB stack — see Go vs Java), and unbounded
new Thread() under load leads straight to OutOfMemoryError. A thread pool
creates a fixed set of worker threads once and feeds them tasks from a queue.
Executors & Futures (Java)
ExecutorService pool = Executors.newFixedThreadPool(8);
Future<Integer> f = pool.submit(() -> expensive()); // queued, runs on a worker
// ... do other work ...
int result = f.get(); // blocks until that task completes
pool.shutdown(); // stop accepting; let running tasks finish
submit returns a Future — a handle to a result that isn't ready yet.
CompletableFuture chains them without blocking (thenApply, thenCompose).
How big should the pool be?
| Workload | Size | Why |
|---|---|---|
| CPU-bound | ≈ number of cores | more threads than cores just adds context-switch overhead |
| IO-bound | cores × (1 + wait/compute) | threads sit blocked on IO, so you need more to keep cores busy |
The dangerous pitfalls
- Pool-induced deadlock: tasks in a bounded pool that wait on other tasks in the same pool can deadlock — all workers occupied, the tasks they wait for stuck in the queue. Never block a pooled task on another task in the same pool.
- Unbounded queue OOM:
newFixedThreadPooluses an unbounded queue — a flood of submissions grows it until OOM. Use a bounded queue + a rejection policy (ThreadPoolExecutor). - Forgetting
shutdown()leaks non-daemon threads and the JVM never exits.
In Go: no pool needed
Goroutines are cheap, so Go's idiom is the worker pool from the Go Concurrency lesson — N
goroutines ranging over a jobs channel. To bound concurrency (the reason Java needs a fixed
pool), use a counting semaphore channel:
sem := make(chan struct{}, 8) // at most 8 in flight
for _, t := range tasks {
sem <- struct{}{} // acquire (blocks if 8 busy)
go func(t Task){ defer func(){ <-sem }(); handle(t) }(t)
}
Takeaways
- Reuse threads via a pool; size by workload (CPU ≈ cores, IO larger).
Future/CompletableFuture= results that aren't ready yet.- Beware pool-induced deadlock and unbounded queues; always
shutdown(). - Go: goroutines + a jobs channel; bound concurrency with a semaphore channel.
Re-authored for this guide; pool diagram hand-authored as SVG. Follows Java Concurrency in Practice ch. 6–8. See also: Go Concurrency (worker pool), Go vs Java (thread cost), Deadlock.
🤖 Don't fully get this? Learn it with Claude
Stuck on Thread Pools, Executors & Futures? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Thread Pools, Executors & Futures** (Concurrency) and want to truly understand it. Explain Thread Pools, Executors & Futures from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Thread Pools, Executors & Futures** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Thread Pools, Executors & Futures** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Thread Pools, Executors & Futures** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.