Java Executor Framework
🔧 What is ExecutorService?
Section titled “🔧 What is ExecutorService?”The ExecutorService is an interface that represents an asynchronous execution mechanism. It provides methods for:
-
Submitting tasks
-
Controlling thread lifecycle
-
Gracefully shutting down threads
It decouples task submission from the details of how each task will be executed.
✨ Why Use ExecutorService?
Section titled “✨ Why Use ExecutorService?”-
Simplifies thread management
-
Allows task scheduling and control
-
Better performance via thread pooling
-
Reduces boilerplate code
✅ Key Methods in ExecutorService
Section titled “✅ Key Methods in ExecutorService”| Method | Description |
|---|---|
submit() | Submits a task for execution and returns a Future |
execute() | Submits a Runnable task for execution (no result) |
shutdown() | Initiates an orderly shutdown |
shutdownNow() | Attempts to stop all actively executing tasks |
awaitTermination() | Waits for the executor to terminate |
🛠️ Thread Pool Usage
Section titled “🛠️ Thread Pool Usage”CPU-Intensive Tasks
Section titled “CPU-Intensive Tasks”Use Executors.newFixedThreadPool(n) where n = # of CPU cores.
Why?
- Prevents excessive context switching.
- Keeps CPU fully utilized.
🔧 Core Interfaces
Section titled “🔧 Core Interfaces”| Interface | Description |
|---|---|
Executor | Base interface with execute(Runnable) |
ExecutorService | Adds lifecycle & submit() (returns Future) support |
ScheduledExecutorService | Adds task scheduling with delay/periodic support |

🧵 What is a Thread Pool?
Section titled “🧵 What is a Thread Pool?”Thread pool = group of pre-initialized threads that execute tasks.
Benefits:
- Reduces thread creation cost
- Controls concurrency
- Efficient CPU and memory usage


Creating Threads in Executors 🧵
Section titled “Creating Threads in Executors 🧵”
🔑 ThreadPoolExecutor Key Concepts
Section titled “🔑 ThreadPoolExecutor Key Concepts”- Core Pool Size - Minimum threads always kept alive.
- Max Pool Size - Max threads if needed.
- Keep-Alive Time - Timeout for idle threads beyond core.
- Work Queue - Tasks stored when all threads are busy.
- Rejection Policies - Decide what happens when queue is full.
✅ ThreadPoolExecutor Example
Section titled “✅ ThreadPoolExecutor Example”ExecutorService pool = new ThreadPoolExecutor( 3, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
for (int i = 0; i < 10; i++) { final int id = i; pool.submit(() -> { System.out.println("Task " + id + " by " + Thread.currentThread().getName()); });}pool.shutdown();🚫 Rejection Policies
Section titled “🚫 Rejection Policies”| Policy | Behavior |
|---|---|
| AbortPolicy (default) | Throws RejectedExecutionException |
| CallerRunsPolicy | Executes task in calling thread |
| DiscardPolicy | Silently drops task |
| DiscardOldestPolicy | Drops oldest unhandled task |
🔀 ForkJoinPool Overview
Section titled “🔀 ForkJoinPool Overview”- Splits tasks into subtasks recursively
- Uses work-stealing to load-balance
🔁 RecursiveTask Example
Section titled “🔁 RecursiveTask Example”class SumTask extends RecursiveTask<Long> { int[] arr; int start, end;
protected Long compute() { if (end - start <= 10) { return Arrays.stream(arr, start, end).sum(); } int mid = (start + end)/2; SumTask left = new SumTask(arr, start, mid); SumTask right = new SumTask(arr, mid, end); left.fork(); right.fork(); return left.join() + right.join(); }}💡 Use Case
Section titled “💡 Use Case”- Recursive tasks like merge sort, matrix ops, recursive searches.
⏰ ScheduledThreadPoolExecutor
Section titled “⏰ ScheduledThreadPoolExecutor”Used for:
- Delayed tasks
- Periodic tasks
schedule()
Section titled “schedule()”scheduler.schedule(() -> { System.out.println("Runs once after 3s");}, 3, TimeUnit.SECONDS);scheduleAtFixedRate()
Section titled “scheduleAtFixedRate()”scheduler.scheduleAtFixedRate(() -> { System.out.println("Runs every 2s");}, 1, 2, TimeUnit.SECONDS);scheduleWithFixedDelay()
Section titled “scheduleWithFixedDelay()”scheduler.scheduleWithFixedDelay(() -> { System.out.println("Delay between runs");}, 1, 3, TimeUnit.SECONDS);⏱️ FixedRate vs FixedDelay
Section titled “⏱️ FixedRate vs FixedDelay”| Type | Behavior |
|---|---|
| FixedRate | Starts every N seconds regardless of task time |
| FixedDelay | Waits N seconds AFTER previous completes |
Analogy:
- FixedRate = Set a timer to toast every 5 minutes ⏲️
- FixedDelay = Wait 5 mins after toast finishes 🧈
🧠 Best Practices
Section titled “🧠 Best Practices”- Use fixed pools for CPU tasks
- Use cached pools for short-lived I/O tasks
- Always
shutdown()executor - Handle
RejectedExecutionException - Monitor using
ThreadPoolExecutor.getQueue()etc.
📊 Summary Table
Section titled “📊 Summary Table”| Executor Type | Best For | Scheduling | Auto-Scaling | Notes |
|---|---|---|---|---|
FixedThreadPool | CPU tasks | ❌ | ❌ | Fixed threads |
CachedThreadPool | Short-lived async tasks | ❌ | ✅ | Unbounded pool |
SingleThreadExecutor | Sequential task processing | ❌ | ❌ | One thread only |
ScheduledThreadPoolExecutor | Scheduled/periodic tasks | ✅ | ❌ | Supports delay/fixed rate |
ForkJoinPool | Parallel recursive tasks | ❌ | ✅ (adaptive) | Uses work stealing |
newFixedThreadPool(int)– Reuses fixed # of threadsnewCachedThreadPool()– Creates threads as needednewSingleThreadExecutor()– One threadnewScheduledThreadPool(int)– Schedule with delay