📞 Call Center Queue Concurrency Problem
🎯 Objective:
Simulate a call center where:
There are a limited number of agents (say 3).
Many customers (calls) are coming in at the same time.
If all agents are busy, new calls must wait in a queue until an agent becomes free.
Only available agents can take calls.
The system should not lose any calls and must not assign 2 agents to the same call.
Solution Approaches
Basic Thread Pool Approach (Fixed Agents)
We'll use a fixed thread pool where:
Each thread represents an agent
Incoming calls are tasks submitted to the executor
The executor automatically handles queuing when all agents are busy
import java.util.concurrent.*; public class BasicCallCenter { // 1. Configuration private static final int AGENT_COUNT = 3; private static ExecutorService agents = Executors.newFixedThreadPool(AGENT_COUNT); // 2. Call Task Representation static class Call implements Runnable { private final int callId; public Call(int id) { this.callId = id; } public void run() { // 3. Call Handling Logic System.out.println("📞 Call " + callId + " started by " + Thread.currentThread().getName()); try { // Simulate variable call duration (2-7 seconds) Thread.sleep(2000 + (long)(Math.random() * 5000)); } catch (InterruptedException e) { System.out.println("❌ Call " + callId + " interrupted"); } System.out.println("✅ Call " + callId + " completed"); } } // 4. Simulation Driver public static void main(String[] args) { // Simulate 10 incoming calls for (int i = 1; i <= 10; i++) { agents.execute(new Call(i)); // 5. Dispatch calls System.out.println("🔔 Received call #" + i); // Random delay between calls (0-1s) try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } // 6. Clean shutdown agents.shutdown(); } }❌ Non-Working Test Cases
1. Sustained Overload (Memory Crash)
Continuous call flood.
10,000 calls with 3 agents
for (int i = 1; i <= 10_000; i++) { agents.execute(new Call(i)); }OutOfMemoryError: Unable to create new native thread
Unbounded queue grows indefinitely, consuming all memory.
2. Call Rejection Needed
Queue at capacity (business requirement), Attempt to queue 6th call when max capacity is 5
Silently accepts all calls
Should reject calls when overloaded
Solution: Use ThreadPoolExecutor with bounded queue:
ExecutorService agents = new ThreadPoolExecutor(
3, 3, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(5), // Bounded queue
new ThreadPoolExecutor.AbortPolicy() // Rejection handler
);
