In the last post of the Executor Framework blog post series, I had written about executing a single task from a collection of tasks, creating a Callable task from a Runnable task, cached Thread Pool and ThreadPoolExecutor
.
ThreadPoolExecutor
class implements ExecutorService
interface.
In this blog post, I’m writing about the following topics related to ThreadPoolExecutor
:
- Changing
RejectedExecutionHandler
policy - Executing a
Runnable
task - Obtaining thread statistics
- Obtaining task statistics
- Defining work to be done before and after execution of each task
- Monitoring the underlying task queue
- Removing tasks from task queue
Changing RejectedExecutionHandler policy
When a bounded queue is used by ThreadPoolExecutor
to hold the tasks submitted for execution and the queue is full, the following four RejectedExecutionHandler
policies decide what happens to the tasks that are added to the queue after it becomes full:
ThreadPoolExecutor.AbortPolicy
– This is the default policy. When the queue is full all tasks added to the queue are rejected andRejectedExecutionException
is thrown.ThreadPoolExecutor.CallerRunsPolicy
– If this policy is applied the thread which called theexecute()
method ofThreadPoolExecutor
, is used to run the task.ThreadPoolExecutor.DiscardPolicy
– The task is discarded without throwing any exception.ThreadPoolExecutor.DiscardOldestPolicy
– The task at the head of queue is removed from the queue.
The RejectedExecutionHandler
can be changed by calling the setRejectedExecutionHandler(RejectedExecutionHandler handler)
method of ThreadPoolExecutor
.
Executing a Runnable task
The execute(Runnable command)
method of ThreadPoolExecutor
submits a Runnable task for execution. The method may execute it immediately or in future. The task may be executed by a new thread or an existing thread from the pool depending on the ThreadPoolExecutor
configuration. If the task submitted for execution is rejected, then the configured RejectedExecutionHandler
decides how the rejected task should be handled.
Obtaining thread statistics
The following methods of ThreadPoolExecutor
enable obtaining thread statistics:
getActiveCount()
- returns the number of threads actively executing tasks.getCorePoolSize()
– returns the count of core threads in the poolgetLargestPoolSize()
– returns the maximum count of threads that concurrently existed in the poolgetMaxiumPoolSize()
– return the maximum number of threads that can run concurrently in the pool.getPoolSize()
– returns the current count of threads in the pool
Obtaining task statistics
The following methods of ThreadPoolExecutor
enable obtaining task statistics:
getCompletedTaskCount()
– returns the count of tasks that are completedgetTaskCount()
– returns the count of tasks that have ever been scheduled for execution
Defining work to be done before and after execution of each task
The beforeExecute(Thread, Runnable)
method can be overridden to define the work that should be done before running each task. The work is defined as Runnable
task which is the second argument and the thread which should perform it is passed as the first argument to this method.
The afterExecute(Runnable, Throwable)
can be overridden to define the work that should be done after the task is executed. It is defined as Runnable task. If the task is terminated and an exception is thrown, it will be represented by the second argument. If the task completes normally then the second argument is null.
The terminated()
method allows defining work that should be done after the ThreadPoolExecutor
is terminated.
Monitoring the underlying task queue
The underlying task queue used by ThreadPoolExecutor
can be accessed by getQueue()
method. Direct usage of the queue except for monitoring purpose is discouraged.
Removing tasks from the task queue
The remove(Runnable task)
method of ThreadPoolExecutor
can be called to remove a task from the task queue. If the task is found in the task queue and it is not already running then it is removed from the task queue. This method returns true if the task is removed.
The purge()
method of ThreadPoolExecutor
tries to remove the cancelled Future
tasks from the task queue. Cancelled tasks may be retained in the task queue until a worker thread removes them. This method helps to reclaim storage memory by trying to remove the cancelled tasks.