ExecutorService vs Raw Thread Creation
Fast recall
Quick revision
Core answer
ExecutorService separates task submission from the way tasks are executed and provides lifecycle methods such as shutdown(). Many implementations use a reusable thread pool, but the interface does not guarantee a fixed or bounded pool. You must choose an executor and queue policy that match the workload.Whether the candidate understands production-grade thread management and the problems with creating raw Thread objects.
Creating a new Thread for every incoming request in a web service, which causes resource exhaustion under load.
Name the Executors factory methods like newFixedThreadPool, explain bounded vs unbounded pools, and mention shutdown vs shutdownNow.
Interview-ready guide
Interview answer
ExecutorService is the Java concurrency abstraction I use to submit Runnable or Callable tasks without hard-wiring each task to a new Thread. It also gives me Future results and an explicit shutdown lifecycle.
A common implementation is a fixed thread pool, which reuses a chosen number of platform threads. That can bound active concurrency, but the usual factory also uses an unbounded work queue, so it does not by itself bound queued work. Other executors use a single worker, grow workers, schedule tasks, or run each task on a virtual thread. I therefore would not say every ExecutorService is a fixed pool. In production I choose the executor and queue policy for the workload, handle task rejection where relevant, and shut down an executor that my component owns.
ExecutorService vs Raw Thread Creation
Direct Answer
ExecutorService separates task submission from the way tasks are executed and provides lifecycle methods such as shutdown(). Many implementations use a reusable thread pool, but the interface does not guarantee a fixed or bounded pool. You must choose an executor and queue policy that match the workload.
Common Mistakes & Pitfalls
- Assuming one platform-thread stack size: reservation and commitment depend on JVM, options, platform, and thread type.
- Calling fixedThreadPool fully bounded: worker count is fixed, but its usual queue is unbounded.
- Treating shutdownNow as force: it requests interruption and returns tasks that never started; tasks must cooperate.
- Losing interruption during shutdown: restore the current thread's status after cleanup.
- Saying execute loses every exception: it provides no Future; an uncaught failure follows the worker's uncaught-exception handling.
Check your understanding
Answer these without looking back at the article.
- What happens to tasks when an ExecutorService is shut down?
- What is the difference between shutdown() and shutdownNow()?
- How does Spring Boot's @Async relate to ExecutorService?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.