Class ThreadPoolTaskExecutor
- All Implemented Interfaces:
Executor,ContextAwareTaskExecutor,ContextAwareTaskExecutorService,MonitorableTaskExecutor,MonitorableTaskExecutorService,TaskExecutor,TaskExecutorService
TaskExecutorService implementation which executes submitted tasks
on a group of threads. This implementation is similar to the
java.util.concurrent.ThreadPoolExecutor in Java but implements
TaskExecutorService instead of ExecutorService.
Note: Consider using ThreadPoolBuilder instead of directly creating
an instance of ThreadPoolTaskExecutor.
Executing new tasks
Tasks can be submitted by one of thesubmit or execute
methods.
When a new task is submitted, ThreadPoolTaskExecutor and there is an
idle thread waiting for tasks to be executed, an attempt will be made to
execute the submitted task on an idle thread and no new thread will be
started. This attempt fails only rarely under extreme contention, in which
case a new thread is started even though there was an idle thread.
In case there is no idle thread waiting and a new thread can be started without exceeding the maximum number of allowed threads, a new thread will be started to execute the submitted task.
In case there is no idle thread waiting and there are already as many threads
executing tasks as allowed, the submitted task will be added to an internal
queue from which the background threads will eventually remove and execute
them. Note that the size of the queue can be limited and if this limit is
reached, the submitting submit or execute method will block
and wait until the task can be added to the queue.
Cancellation of tasks
Canceling a task which was not yet started and is still in the queue will immediately remove it from the queue and no references will be retained to the task (allowing it to be garbage collected if not referenced by external code).
Canceling a task will cause the CancellationToken passed to it,
signal cancellation request. In this case the task may decide if it is to be
canceled or not. If the task throws an OperationCanceledException,
task execution is considered to be canceled. Note that if the task throws
an OperationCanceledException it is always assumed to be canceled,
even if the CancellationToken does not signal a cancellation request.
Number of referenced tasks
The maximum number of tasks referenced by aThreadPoolTaskExecutor
at any given time is the maximum size of its queue plus the maximum number of
allowed threads. The ThreadPoolTaskExecutor will never reference
tasks more than this. Note however, that not yet returned execute
methods always reference their task specified in their argument
(obviously this is unavoidable) and there is no limit on how many
times the user can concurrently call these methods.
Terminating ThreadPoolTaskExecutor
The ThreadPoolTaskExecutor must always be shut down when no longer
needed, so that it may shutdown its threads. If the user fails to shut down
the ThreadPoolTaskExecutor (either by calling shutdown() or
shutdownAndCancel()) and the garbage collector notifies the
ThreadPoolTaskExecutor that it has become unreachable (through
finalizers), it will be logged as an error using the logging facility of Java
(in a Level.SEVERE log message).
Comparison with ThreadPoolExecutor
| Feature | ThreadPoolTaskExecutor | ThreadPoolExecutor |
|---|---|---|
| Immediate cancellation | Yes. | No, tasks remain in the queue until attempted to be executed. |
| Cancellation strategy of executing tasks | Relies on a CancellationToken. |
Relies on thread interrupts. |
| Tracking the state of a submitted task |
Not directly. Submitted tasks must be wrapped and CompletionStage
must be used to listen for completion
|
Possible using the returned Future. |
| Waiting until the task finished executing | Possible using the returned CompletionStage. |
Not possible, if task was canceled by shutdownNow. |
| Do cleanup even if task was canceled | Yes, using the returned CompletionStage. |
No, only if the task was refused when submitting. |
| User defined thread factory | Yes | Yes |
| Automatically stop idle threads | Yes | Yes |
| Limit the number of threads | Yes | Yes |
| New thread start policy | Starts a new thread only if there are no idle threads and the maximum number of threads was not reached. | Starts a new thread always unless the maximum number of threads was reached. |
| Increase number of threads over the limit, if queue is full | No | Yes and configurable |
| User defined implementation for the internal queue | No | Yes |
| Throttle, when the task queue is large | Yes | Yes, with some limitations |
| Asynchronous notification of termination | Yes | Only to subclasses |
| Shut down and cancel submitted tasks | Yes | Yes |
Thread safety
Methods of this class are safely accessible from multiple threads concurrently.Synchronization transparency
Method of this class are not synchronization transparent unless otherwise noted.- See Also:
-
Field Summary
Fields inherited from class org.jtrim2.executor.DelegatedTaskExecutorService
wrappedExecutor -
Constructor Summary
ConstructorsConstructorDescriptionThreadPoolTaskExecutor(String poolName) Creates a newThreadPoolTaskExecutorinitialized with specified name.ThreadPoolTaskExecutor(String poolName, int maxThreadCount) Creates a newThreadPoolTaskExecutorinitialized with the given properties.ThreadPoolTaskExecutor(String poolName, int maxThreadCount, int maxQueueSize) Creates a newThreadPoolTaskExecutorinitialized with the given properties.ThreadPoolTaskExecutor(String poolName, int maxThreadCount, int maxQueueSize, long idleTimeout, TimeUnit timeUnit) Creates a newThreadPoolTaskExecutorinitialized with the given properties. -
Method Summary
Modifier and TypeMethodDescriptionvoidSpecifies that thisThreadPoolTaskExecutordoes not need to be shut down.longgetIdleTimeout(TimeUnit timeUnit) Returns the currently set timeout value after idle threads should stop.intReturns the currently set maximum size for the queue of tasks scheduled to be executed.intReturns the currently set maximum thread to be used by this executor.longReturns the approximate number of tasks currently being executed.longReturns the approximate number of tasks currently queued to this executor.Returns the name of thisThreadPoolTaskExecutoras specified at construction time.booleanReturnstrueif the calling code is executing in the context of this executor.voidsetIdleTimeout(long idleTimeout, TimeUnit timeUnit) Sets the timeout value after idle threads should terminate.voidsetMaxQueueSize(int maxQueueSize) Sets the maximum number of tasks allowed to be stored in the internal queue.voidsetMaxThreadCount(int maxThreadCount) Sets the maximum number of threads allowed to execute submitted tasks concurrently.voidsetThreadFactory(ThreadFactory threadFactory) Sets theThreadFactorywhich is used to create worker threads for this executor.voidshutdown()Shuts down thisTaskExecutorService, so that it will not execute tasks submitted to it after this method call returns.voidShuts down thisTaskExecutorServiceand cancels already submitted tasks, so that it will not execute tasks submitted to it after this method call returns.toString()Returns the string representation of this executor in no particular format.Methods inherited from class org.jtrim2.executor.DelegatedTaskExecutorService
addTerminateListener, awaitTermination, execute, execute, executeFunction, executeStaged, isShutdown, isTerminated, tryAwaitTerminationMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.jtrim2.executor.TaskExecutor
execute, execute, executeFunction, executeStagedMethods inherited from interface org.jtrim2.executor.TaskExecutorService
addTerminateListener, awaitTermination, isShutdown, isTerminated, tryAwaitTermination
-
Constructor Details
-
ThreadPoolTaskExecutor
Creates a newThreadPoolTaskExecutorinitialized with specified name.The default maximum number of threads is
Runtime.getRuntime().availableProcessors().The default maximum queue size is
Integer.MAX_VALUEmaking it effectively unbounded.The default timeout value after idle threads stop is 5 seconds.
The newly created
ThreadPoolTaskExecutorwill not have any thread started. Threads will only be started when submitting tasks (as required).Note: Consider using
ThreadPoolBuilderinstead of directly creating an instance ofThreadPoolTaskExecutor.- Parameters:
poolName- the name of thisThreadPoolTaskExecutorfor logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot benull.- Throws:
IllegalArgumentException- thrown if an illegal value was specified for any of theintargumentsNullPointerException- thrown if the specified name for thisThreadPoolTaskExecutorisnull
-
ThreadPoolTaskExecutor
Creates a newThreadPoolTaskExecutorinitialized with the given properties.The default maximum queue size is
Integer.MAX_VALUEmaking it effectively unbounded.The default timeout value after idle threads stop is 5 seconds.
The newly created
ThreadPoolTaskExecutorwill not have any thread started. Threads will only be started when submitting tasks (as required).Note: Consider using
ThreadPoolBuilderinstead of directly creating an instance ofThreadPoolTaskExecutor.- Parameters:
poolName- the name of thisThreadPoolTaskExecutorfor logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot benull.maxThreadCount- the maximum number of threads to be executing submitted tasks concurrently. TheThreadPoolTaskExecutorwill never execute more tasks concurrently as this number. This argument must be greater than or equal to 1.- Throws:
IllegalArgumentException- thrown if an illegal value was specified for any of theintargumentsNullPointerException- thrown if the specified name for thisThreadPoolTaskExecutorisnull
-
ThreadPoolTaskExecutor
Creates a newThreadPoolTaskExecutorinitialized with the given properties.The default timeout value after idle threads stop is 5 seconds.
The newly created
ThreadPoolTaskExecutorwill not have any thread started. Threads will only be started when submitting tasks (as required).Note: Consider using
ThreadPoolBuilderinstead of directly creating an instance ofThreadPoolTaskExecutor.- Parameters:
poolName- the name of thisThreadPoolTaskExecutorfor logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot benull.maxThreadCount- the maximum number of threads to be executing submitted tasks concurrently. TheThreadPoolTaskExecutorwill never execute more tasks concurrently as this number. This argument must be greater than or equal to 1.maxQueueSize- the maximum size of the internal queue to store tasks not yet executed due to all threads being busy executing tasks. This argument must be greater than or equal to 1 and is recommended to be (but not required) greater than or equal tomaxThreadCount.- Throws:
IllegalArgumentException- thrown if an illegal value was specified for any of theintargumentsNullPointerException- thrown if the specified name for thisThreadPoolTaskExecutorisnull
-
ThreadPoolTaskExecutor
public ThreadPoolTaskExecutor(String poolName, int maxThreadCount, int maxQueueSize, long idleTimeout, TimeUnit timeUnit) Creates a newThreadPoolTaskExecutorinitialized with the given properties.The newly created
ThreadPoolTaskExecutorwill not have any thread started. Threads will only be started when submitting tasks (as required).Note: Consider using
ThreadPoolBuilderinstead of directly creating an instance ofThreadPoolTaskExecutor.- Parameters:
poolName- the name of thisThreadPoolTaskExecutorfor logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot benull.maxThreadCount- the maximum number of threads to be executing submitted tasks concurrently. TheThreadPoolTaskExecutorwill never execute more tasks concurrently as this number. This argument must be greater than or equal to 1.maxQueueSize- the maximum size of the internal queue to store tasks not yet executed due to all threads being busy executing tasks. This argument must be greater than or equal to 1 and is recommended to be (but not required) greater than or equal tomaxThreadCount.idleTimeout- the time in the given time unit after idle threads should stop. That is if a thread goes idle (i.e.: there are no submitted tasks), it will wait this amount of time before giving up waiting for submitted tasks. The thread may be restarted if needed later. It is recommended to use a reasonably low value for this argument (but not too low), so even if thisThreadPoolTaskExecutorhas not been shut down (due to a bug), threads will still terminate allowing the JVM to terminate as well (if there are no more non-daemon threads). This argument must be greater than or equal to zero.timeUnit- the time unit of theidleTimeoutargument. This argument cannot benull.- Throws:
IllegalArgumentException- thrown if an illegal value was specified for any of theintargumentsNullPointerException- thrown if any of the arguments isnull
-
-
Method Details
-
dontNeedShutdown
public void dontNeedShutdown()Specifies that thisThreadPoolTaskExecutordoes not need to be shut down. Calling this method prevents this executor to be shut down automatically when there is no more reference to this executor, which also prevents logging a message if this executor has not been shut down. This method might be called if you do not plan to shutdown this executor but instead want to rely on the threads of this executor to automatically shutdown after a small timeout. -
setThreadFactory
Sets theThreadFactorywhich is used to create worker threads for this executor. Already started workers are not affected by this method call but workers created after this method call will use the currently setThreadFactory.It is recommended to call this method before submitting any task to this executor. Doing so guarantees that all worker threads of this executor will be created by the specified
ThreadFactory.The default
ThreadFactoryused by this executor is aExecutorsEx.NamedThreadFactorycreating non-daemon threads.- Parameters:
threadFactory- theThreadFactorywhich is used to create worker threads for this executor. This argument cannot benull.- Throws:
NullPointerException- thrown if the specified thread factory isnull
-
shutdown
public void shutdown()Shuts down thisTaskExecutorService, so that it will not execute tasks submitted to it after this method call returns.Already submitted tasks will execute normally but tasks submitted after this method returns will immediately be completed exceptionally with an
OperationCanceledException.Note that it is possible, that some tasks are submitted concurrently with this call. Those tasks can be either canceled or executed normally, depending on the circumstances.
If currently executing tasks should be canceled as well, use the
TaskExecutorService.shutdownAndCancel()method to shutdown thisTaskExecutorService.This method call is idempotent. That is, calling it multiple times must have no further effect.
- Specified by:
shutdownin interfaceTaskExecutorService- Overrides:
shutdownin classDelegatedTaskExecutorService- See Also:
-
shutdownAndCancel
public void shutdownAndCancel()Shuts down thisTaskExecutorServiceand cancels already submitted tasks, so that it will not execute tasks submitted to it after this method call returns.Already submitted tasks will be canceled and the tasks may detect this cancellation request by inspecting their
CancellationTokenbut tasks submitted after this method returns will immediately be completed exceptionally with anOperationCanceledException.Note that it is possible, that some tasks are submitted concurrently with this call. Those tasks may be treated as if they were submitted before this method call or as if they were submitted after.
If currently executing tasks should be left executing, use the
TaskExecutorService.shutdown()method instead to shutdown thisTaskExecutorService.This method call is idempotent. That is, calling it multiple times must have no further effect. Note however, that calling this method after the
shutdown()method is meaningful because this method will cancel ongoing tasks.- Specified by:
shutdownAndCancelin interfaceTaskExecutorService- Overrides:
shutdownAndCancelin classDelegatedTaskExecutorService- See Also:
-
getNumberOfQueuedTasks
public long getNumberOfQueuedTasks()Returns the approximate number of tasks currently queued to this executor. The queued tasks are not currently executing but are scheduled to be executed in the future.Note that the value returned by this method should be considered unreliable and cannot be used for synchronization purposes.
- Specified by:
getNumberOfQueuedTasksin interfaceMonitorableTaskExecutor- Returns:
- the approximate number of tasks currently queued to this executor. This method always returns a value greater than or equal to zero.
-
getNumberOfExecutingTasks
public long getNumberOfExecutingTasks()Returns the approximate number of tasks currently being executed.Note that the value returned by this method should be considered unreliable and cannot be used for synchronization purposes.
- Specified by:
getNumberOfExecutingTasksin interfaceMonitorableTaskExecutor- Returns:
- the approximate number of tasks currently being executed. This method always returns a value greater than or equal to zero.
-
isExecutingInThis
public boolean isExecutingInThis()Returnstrueif the calling code is executing in the context of this executor. That is, it is executed by a task submitted to this executor.This method can be used to check that a method call is executing in the context it was designed for.
- Specified by:
isExecutingInThisin interfaceContextAwareTaskExecutor- Returns:
trueif the calling code is executing in the context of this executor,falseotherwise
-
setMaxThreadCount
public void setMaxThreadCount(int maxThreadCount) Sets the maximum number of threads allowed to execute submitted tasks concurrently.Setting this property may not have an immediate effect. Setting it to a higher value as was set previously, will not cause new thread to be started if the internal queue is not empty but subsequent
submitandexecutemethods will detect that they can start new threads. Setting this property to a lower value as was set previously, will not cause threads to stop even if they are currently idle. It just prevents new threads to be created until the number of currently running threads drops below this limit (as threads stop due to too long idle time).Note that setting this property before a task was submitted to this
ThreadPoolTaskExecutoris guaranteed to have immediate effect.- Parameters:
maxThreadCount- the maximum number of threads allowed to be executing submitted tasks concurrently. This argument must be greater than or equal to 1.- Throws:
IllegalArgumentException- if the specifiedmaxThreadCountis less than 1
-
getMaxThreadCount
public int getMaxThreadCount()Returns the currently set maximum thread to be used by this executor.The return value of this method is for information purpose only. Due to concurrent sets and already started threads, there is no guarantee that the return value is truly being honored at the moment. See
setMaxThreadCountfor details on how this property works.- Returns:
- the currently set maximum thread to be used by this executor. This value is always greater than or equal to one.
-
setMaxQueueSize
public void setMaxQueueSize(int maxQueueSize) Sets the maximum number of tasks allowed to be stored in the internal queue.Setting this property higher than it was set previously will have an immediate effect and currently blocking
submitandexecutewill recheck if they can add the submitted task to the queue. Setting this property lower, however, will not remove tasks from the queue but will prevent more tasks to be added to the queue before the number of tasks in the queue drops below this limit.- Parameters:
maxQueueSize- the maximum number of tasks allowed to be stored in the internal queue. This argument must be greater than or equal to 1.- Throws:
IllegalArgumentException- if the specifiedmaxQueueSizeis less than 1
-
getMaxQueueSize
public int getMaxQueueSize()Returns the currently set maximum size for the queue of tasks scheduled to be executed.The return value of this method is for information purpose only. Due to concurrent sets and already queued tasks, there is no guarantee that the return value is truly being honored at the moment. See
setMaxQueueSizefor details on how this property works.- Returns:
- the currently set maximum size for the queue of tasks scheduled to be executed. This value is always greater than or equal to one.
-
setIdleTimeout
Sets the timeout value after idle threads should terminate. That is, threads will terminate if they waited for at least this much time and there was no submitted task for them to execute.Setting this property has an immediate effect.
- Parameters:
idleTimeout- the timeout value in the given time unit after idle threads should terminate. This argument must be greater than or equal to zero.timeUnit- the time unit of theidleTimeoutargument. This argument cannot benull.- Throws:
IllegalArgumentException- thrown if the specified timeout value is less than zeroNullPointerException- thrown if the specified time unit argument isnull
-
getIdleTimeout
Returns the currently set timeout value after idle threads should stop.The return value of this method is for information purpose only. Due to concurrent sets, there is no guarantee that the return value is truly being honored at the moment. See
setIdleTimeoutfor details on how this property works.- Parameters:
timeUnit- the time unit in which the result is request. This argument cannot benull.- Returns:
- the currently set timeout value after idle threads should stop.
The return value might not be exactly what was set by the previous
invocation to
setIdleTimeoutdue to rounding errors. This method always returns a values greater than or equal to zero. - Throws:
NullPointerException- thrown if the specified time unit isnull
-
getPoolName
Returns the name of thisThreadPoolTaskExecutoras specified at construction time.- Returns:
- the name of this
ThreadPoolTaskExecutoras specified at construction time. This method never returnsnull.
-
toString
Returns the string representation of this executor in no particular format.This method is intended to be used for debugging only.
- Overrides:
toStringin classDelegatedTaskExecutorService- Returns:
- the string representation of this object in no particular format.
This method never returns
null.
-