Class BlockingExecutorService

  • All Implemented Interfaces:
    Executor, ExecutorService

    public class BlockingExecutorService
    extends Object
    implements ExecutorService
    Wrap a ThreadPoolExecutor with an ExecutorService implementation that blocks the thread attempting to submit a task when the task queue is full, rather than rejecting the submitted task (as ThreadPoolExecutor does).

    This can be useful in applications where there is a finite but large number of tasks to be processed by the ExecutorService, so the task queue of pending submitted tasks would have to be unreasonably large to prevent the thread(s) generating Runnable or Callable instances from experiencing task rejection (a RejectedExecutionException). With a ThreadPoolExecutor this would result in rejected tasks. With this class, the task-submitting thread can be throttled simply by the fact that submit(java.util.concurrent.Callable<T>) will block until the work queue of the enclosed ThreadPoolExecutor has enough space to enqueue the task.

    A similar effect can be produced by the ThreadPoolExecutor's ThreadPoolExecutor.CallerRunsPolicy, but in that case, the decision to run tasks on the task-generating thread creates situations where a long-running task would keeping the task-generating caller busy, resulting in threads in the ThreadPoolExecutor finishing their own tasks and then being starved for new tasks. This drawback could be partly mitigated by lengthening the work queue (to try and ensure that there are enough pending tasks in the queue to keep the worker threads busy until the work-generating thread is finished and can fill the queue with more tasks) but that means the caller has to estimate how big the queue will need to be based on how long a task will take to finish.

    This class embodies a simpler solution from the caller's perspective, which is to just block the task-generating thread(s) while the queue is full, allowing it to run whenever the queue has available space to fill.