What are the saturation / rejection policies of a thread… — Cracked Java
// Concurrency & Multithreading · Executors & Thread Pools
MidTheory

What are the saturation / rejection policies of a thread pool?

When a ThreadPoolExecutor cannot accept a task — both the queue is full and the pool is at maximumPoolSize (or the pool has been shut down) — it invokes a RejectedExecutionHandler. The JDK ships four, and you can write your own.

The four built-in policies

  • AbortPolicy (the default) — throws RejectedExecutionException. Loud and fail-fast; the caller must catch it. Good when dropping work silently would be a bug.
  • CallerRunsPolicy — runs the task on the calling thread instead of a pool thread. This is the elegant one: the caller is busy running the rejected task, so it can't submit more, which throttles the producer and creates natural back-pressure. The submission rate self-limits to what the pool can drain.
  • DiscardPolicy — silently drops the task. No exception, no log. Only acceptable when losing tasks is genuinely fine (e.g. best-effort metrics).
  • DiscardOldestPolicy — drops the oldest queued task and retries the new one. Useful for "latest value wins" workloads; dangerous if older tasks matter.
ThreadPoolExecutor pool = new ThreadPoolExecutor(
    4, 8, 60, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100),
    new ThreadPoolExecutor.CallerRunsPolicy());   // back-pressure on overload

// Custom: bounded blocking instead of dropping
RejectedExecutionHandler blockingHandler = (task, executor) -> {
    try {
        executor.getQueue().put(task);            // blocks the submitter until space frees
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RejectedExecutionException(e);
    }
};

Choosing one

Rejection only happens with a bounded queue (an unbounded queue never fills, so the handler is never called). For request-serving systems, CallerRunsPolicy is the usual choice because it degrades latency gracefully instead of either dropping requests or exploding memory. The custom blocking handler above gives true producer back-pressure for ingestion pipelines.

Mark your status