Package org.springframework.scheduling.concurrent

# Class ThreadPoolTaskExecutor

java.lang.Object
org.springframework.util.CustomizableThreadCreator
org.springframework.scheduling.concurrent.CustomizableThreadFactory
org.springframework.scheduling.concurrent.ExecutorConfigurationSupport
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

All Implemented Interfaces:
  `Serializable`, `Executor`, `ThreadFactory`, `EventListener`, `org.springframework.beans.factory.Aware`, `org.springframework.beans.factory.BeanNameAware`, `org.springframework.beans.factory.DisposableBean`, `org.springframework.beans.factory.InitializingBean`, `ApplicationContextAware`, `ApplicationListener<ContextClosedEvent>`, `Lifecycle`, `Phased`, `SmartLifecycle`, `org.springframework.core.task.AsyncListenableTaskExecutor`, `org.springframework.core.task.AsyncTaskExecutor`, `org.springframework.core.task.TaskExecutor`, `SchedulingTaskExecutor`

public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements org.springframework.core.task.AsyncListenableTaskExecutor, SchedulingTaskExecutor
JavaBean that allows for configuring a `ThreadPoolExecutor` in bean style (through its "corePoolSize", "maxPoolSize", "keepAliveSeconds", "queueCapacity" properties) and exposing it as a Spring `TaskExecutor`. This class is also well suited for management and monitoring (for example, through JMX), providing several useful attributes: "corePoolSize", "maxPoolSize", "keepAliveSeconds" (all supporting updates at runtime); "poolSize", "activeCount" (for introspection only).

The default configuration is a core pool size of 1, with unlimited max pool size and unlimited queue capacity. This is roughly equivalent to `Executors.newSingleThreadExecutor()`, sharing a single thread for all tasks. Setting `"queueCapacity"` to 0 mimics `Executors.newCachedThreadPool()`, with immediate scaling of threads in the pool to a potentially very high number. Consider also setting a `"maxPoolSize"` at that point, as well as possibly a higher `"corePoolSize"` (see also the `"allowCoreThreadTimeOut"` mode of scaling).

NOTE: This class implements Spring's `TaskExecutor` interface as well as the `Executor` interface, with the former being the primary interface, the other just serving as secondary convenience. For this reason, the exception handling follows the TaskExecutor contract rather than the Executor contract, in particular regarding the `TaskRejectedException`.

For an alternative, you may set up a ThreadPoolExecutor instance directly using constructor injection, or use a factory method definition that points to the `Executors` class. To expose such a raw Executor as a Spring `TaskExecutor`, simply wrap it with a `ConcurrentTaskExecutor` adapter.

Since:
  2.0
Author:
  Juergen Hoeller, Rémy Guihard, Sam Brannen
See Also:
  - `TaskExecutor`
  - `ThreadPoolExecutor`
  - `ThreadPoolExecutorFactoryBean`
  - `ConcurrentTaskExecutor`
  - Serialized Form

## Field Summary

### Fields inherited from class org.springframework.scheduling.concurrent.ExecutorConfigurationSupport

`DEFAULT_PHASE, logger`

### Fields inherited from interface org.springframework.core.task.AsyncTaskExecutor

`TIMEOUT_IMMEDIATE, TIMEOUT_INDEFINITE`

## Constructor Summary

Constructors
Constructor
Description
`ThreadPoolTaskExecutor()`

## Method Summary

Modifier and Type
Method
Description
`protected void`
`cancelRemainingTask(Runnable task)`
Cancel the given remaining task which never commenced execution, as returned from `ExecutorService.shutdownNow()`.
`protected BlockingQueue<Runnable>`
`createQueue(int queueCapacity)`
Create the BlockingQueue to use for the ThreadPoolExecutor.
`void`
`execute(Runnable task)`
`int`
`getActiveCount()`
Return the number of currently active threads.
`int`
`getCorePoolSize()`
Return the ThreadPoolExecutor's core pool size.
`int`
`getKeepAliveSeconds()`
Return the ThreadPoolExecutor's keep-alive seconds.
`int`
`getMaxPoolSize()`
Return the ThreadPoolExecutor's maximum pool size.
`int`
`getPoolSize()`
Return the current pool size.
`int`
`getQueueCapacity()`
Return the capacity for the ThreadPoolExecutor's BlockingQueue.
`int`
`getQueueSize()`
Return the current queue size.
`ThreadPoolExecutor`
`getThreadPoolExecutor()`
Return the underlying ThreadPoolExecutor for native access.
`protected ExecutorService`
`initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler)`
Note: This method exposes an `ExecutorService` to its base class but stores the actual `ThreadPoolExecutor` handle internally.
`protected void`
`initiateEarlyShutdown()`
Early shutdown signal: do not trigger further tasks, let existing tasks complete before hitting the actual destruction step in the `ExecutorConfigurationSupport.shutdown()` method.
`void`
`setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut)`
Specify whether to allow core threads to time out.
`void`
`setCorePoolSize(int corePoolSize)`
Set the ThreadPoolExecutor's core pool size.
`void`
`setKeepAliveSeconds(int keepAliveSeconds)`
Set the ThreadPoolExecutor's keep-alive seconds.
`void`
`setMaxPoolSize(int maxPoolSize)`
Set the ThreadPoolExecutor's maximum pool size.
`void`
`setPrestartAllCoreThreads(boolean prestartAllCoreThreads)`
Specify whether to start all core threads, causing them to idly wait for work.
`void`
`setQueueCapacity(int queueCapacity)`
Set the capacity for the ThreadPoolExecutor's BlockingQueue.
`void`
`setStrictEarlyShutdown(boolean strictEarlyShutdown)`
Specify whether to initiate an early shutdown signal on context close, disposing all idle threads and rejecting further task submissions.
`void`
`setTaskDecorator(org.springframework.core.task.TaskDecorator taskDecorator)`
Specify a custom `TaskDecorator` to be applied to any `Runnable` about to be executed.
`Future<?>`
`submit(Runnable task)`
`<T> Future<T>`
`submit(Callable<T> task)`
`org.springframework.util.concurrent.ListenableFuture<?>`
`submitListenable(Runnable task)`
`<T> org.springframework.util.concurrent.ListenableFuture<T>`
`submitListenable(Callable<T> task)`

### Methods inherited from class org.springframework.scheduling.concurrent.ExecutorConfigurationSupport

`afterExecute, afterPropertiesSet, beforeExecute, destroy, getPhase, initialize, initiateShutdown, isRunning, onApplicationEvent, setAcceptTasksAfterContextClose, setApplicationContext, setAwaitTerminationMillis, setAwaitTerminationSeconds, setBeanName, setPhase, setRejectedExecutionHandler, setThreadFactory, setThreadNamePrefix, setVirtualThreads, setWaitForTasksToCompleteOnShutdown, shutdown, start, stop, stop`

### Methods inherited from class org.springframework.scheduling.concurrent.CustomizableThreadFactory

`newThread`

### Methods inherited from class org.springframework.util.CustomizableThreadCreator

`createThread, getDefaultThreadNamePrefix, getThreadGroup, getThreadNamePrefix, getThreadPriority, isDaemon, nextThreadName, setDaemon, setThreadGroup, setThreadGroupName, setThreadPriority`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.springframework.context.ApplicationListener

`supportsAsyncExecution`

### Methods inherited from interface org.springframework.core.task.AsyncTaskExecutor

`execute, submitCompletable, submitCompletable`

### Methods inherited from interface org.springframework.scheduling.SchedulingTaskExecutor

`prefersShortLivedTasks`

### Methods inherited from interface org.springframework.context.SmartLifecycle

`isAutoStartup`

## Constructor Details

### ThreadPoolTaskExecutor

public ThreadPoolTaskExecutor()

## Method Details

### setCorePoolSize

public void setCorePoolSize(int corePoolSize)
Set the ThreadPoolExecutor's core pool size. Default is 1.

This setting can be modified at runtime, for example through JMX.

### getCorePoolSize

public int getCorePoolSize()
Return the ThreadPoolExecutor's core pool size.

### setMaxPoolSize

public void setMaxPoolSize(int maxPoolSize)
Set the ThreadPoolExecutor's maximum pool size. Default is `Integer.MAX_VALUE`.

This setting can be modified at runtime, for example through JMX.

### getMaxPoolSize

public int getMaxPoolSize()
Return the ThreadPoolExecutor's maximum pool size.

### setKeepAliveSeconds

public void setKeepAliveSeconds(int keepAliveSeconds)
Set the ThreadPoolExecutor's keep-alive seconds.

Default is 60.

This setting can be modified at runtime, for example through JMX.

### getKeepAliveSeconds

public int getKeepAliveSeconds()
Return the ThreadPoolExecutor's keep-alive seconds.

### setQueueCapacity

public void setQueueCapacity(int queueCapacity)
Set the capacity for the ThreadPoolExecutor's BlockingQueue.

Default is `Integer.MAX_VALUE`.

Any positive value will lead to a LinkedBlockingQueue instance; any other value will lead to a SynchronousQueue instance.

See Also:
  - `LinkedBlockingQueue`
  - `SynchronousQueue`

### getQueueCapacity

public int getQueueCapacity()
Return the capacity for the ThreadPoolExecutor's BlockingQueue.

Since:
  5.3.21
See Also:
  - `setQueueCapacity(int)`

### setAllowCoreThreadTimeOut

public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut)
Specify whether to allow core threads to time out. This enables dynamic growing and shrinking even in combination with a non-zero queue (since the max pool size will only grow once the queue is full).

Default is "false".

See Also:
  - `ThreadPoolExecutor.allowCoreThreadTimeOut(boolean)`

### setPrestartAllCoreThreads

public void setPrestartAllCoreThreads(boolean prestartAllCoreThreads)
Specify whether to start all core threads, causing them to idly wait for work.

Default is "false", starting threads and adding them to the pool on demand.

Since:
  5.3.14
See Also:
  - `ThreadPoolExecutor.prestartAllCoreThreads()`

### setStrictEarlyShutdown

public void setStrictEarlyShutdown(boolean strictEarlyShutdown)
Specify whether to initiate an early shutdown signal on context close, disposing all idle threads and rejecting further task submissions.

By default, existing tasks will be allowed to complete within the coordinated lifecycle stop phase in any case. This setting just controls whether an explicit `ThreadPoolExecutor.shutdown()` call will be triggered on context close, rejecting task submissions after that point.

As of 6.1.4, the default is "false", leniently allowing for late tasks to arrive after context close, still participating in the lifecycle stop phase. Note that this differs from `ExecutorConfigurationSupport.setAcceptTasksAfterContextClose(boolean)` which completely bypasses the coordinated lifecycle stop phase, with no explicit waiting for the completion of existing tasks at all.

Switch this to "true" for a strict early shutdown signal analogous to the 6.1-established default behavior of `ThreadPoolTaskScheduler`. Note that the related flags `ExecutorConfigurationSupport.setAcceptTasksAfterContextClose(boolean)` and `ExecutorConfigurationSupport.setWaitForTasksToCompleteOnShutdown(boolean)` will override this setting, leading to a late shutdown without a coordinated lifecycle stop phase.

Since:
  6.1.4
See Also:
  - `ExecutorConfigurationSupport.initiateShutdown()`

### setTaskDecorator

public void setTaskDecorator(org.springframework.core.task.TaskDecorator taskDecorator)
Specify a custom `TaskDecorator` to be applied to any `Runnable` about to be executed.

Note that such a decorator is not necessarily being applied to the user-supplied `Runnable`/`Callable` but rather to the actual execution callback (which may be a wrapper around the user-supplied task).

The primary use case is to set some execution context around the task's invocation, or to provide some monitoring/statistics for task execution.

NOTE: Exception handling in `TaskDecorator` implementations is limited to plain `Runnable` execution via `execute` calls. In case of `#submit` calls, the exposed `Runnable` will be a `FutureTask` which does not propagate any exceptions; you might have to cast it and call `Future#get` to evaluate exceptions. See the `ThreadPoolExecutor#afterExecute` javadoc for an example of how to access exceptions in such a `Future` case.

Since:
  4.3

### initializeExecutor

protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler)
Note: This method exposes an `ExecutorService` to its base class but stores the actual `ThreadPoolExecutor` handle internally. Do not override this method for replacing the executor, rather just for decorating its `ExecutorService` handle or storing custom state.

Specified by:
  `initializeExecutor` in class `ExecutorConfigurationSupport`
Parameters:
  `threadFactory` - the ThreadFactory to use
  `rejectedExecutionHandler` - the RejectedExecutionHandler to use
Returns:
  a new ExecutorService instance
See Also:
  - `ExecutorConfigurationSupport.afterPropertiesSet()`

### createQueue

protected BlockingQueue<Runnable> createQueue(int queueCapacity)
Create the BlockingQueue to use for the ThreadPoolExecutor.

A LinkedBlockingQueue instance will be created for a positive capacity value; a SynchronousQueue otherwise.

Parameters:
  `queueCapacity` - the specified queue capacity
Returns:
  the BlockingQueue instance
See Also:
  - `LinkedBlockingQueue`
  - `SynchronousQueue`

### getThreadPoolExecutor

public ThreadPoolExecutor getThreadPoolExecutor() throws IllegalStateException
Return the underlying ThreadPoolExecutor for native access.

Returns:
  the underlying ThreadPoolExecutor (never `null`)
Throws:
  `IllegalStateException` - if the ThreadPoolTaskExecutor hasn't been initialized yet

### getPoolSize

public int getPoolSize()
Return the current pool size.

See Also:
  - `ThreadPoolExecutor.getPoolSize()`

### getQueueSize

public int getQueueSize()
Return the current queue size.

Since:
  5.3.21
See Also:
  - `ThreadPoolExecutor.getQueue()`

### getActiveCount

public int getActiveCount()
Return the number of currently active threads.

See Also:
  - `ThreadPoolExecutor.getActiveCount()`

### execute

public void execute(Runnable task)

Specified by:
  `execute` in interface `Executor`
Specified by:
  `execute` in interface `org.springframework.core.task.TaskExecutor`

### submit

public Future<?> submit(Runnable task)

Specified by:
  `submit` in interface `org.springframework.core.task.AsyncTaskExecutor`

### submit

public <T> Future<T> submit(Callable<T> task)

Specified by:
  `submit` in interface `org.springframework.core.task.AsyncTaskExecutor`

### submitListenable

public org.springframework.util.concurrent.ListenableFuture<?> submitListenable(Runnable task)

Specified by:
  `submitListenable` in interface `org.springframework.core.task.AsyncListenableTaskExecutor`

### submitListenable

public <T> org.springframework.util.concurrent.ListenableFuture<T> submitListenable(Callable<T> task)

Specified by:
  `submitListenable` in interface `org.springframework.core.task.AsyncListenableTaskExecutor`

### cancelRemainingTask

protected void cancelRemainingTask(Runnable task)
Description copied from class: `ExecutorConfigurationSupport`
Cancel the given remaining task which never commenced execution, as returned from `ExecutorService.shutdownNow()`.

Overrides:
  `cancelRemainingTask` in class `ExecutorConfigurationSupport`
Parameters:
  `task` - the task to cancel (typically a `RunnableFuture`)
See Also:
  - `ExecutorConfigurationSupport.shutdown()`
  - `Future.cancel(boolean)`

### initiateEarlyShutdown

protected void initiateEarlyShutdown()
Description copied from class: `ExecutorConfigurationSupport`
Early shutdown signal: do not trigger further tasks, let existing tasks complete before hitting the actual destruction step in the `ExecutorConfigurationSupport.shutdown()` method. This goes along with a `coordinated lifecycle stop phase`.

Called from `ExecutorConfigurationSupport.onApplicationEvent(ContextClosedEvent)` if no indications for a late shutdown have been determined, that is, if the `"acceptTasksAfterContextClose` and `"waitForTasksToCompleteOnShutdown"` flags have not been set.

The default implementation calls `ExecutorConfigurationSupport.initiateShutdown()`.

Overrides:
  `initiateEarlyShutdown` in class `ExecutorConfigurationSupport`
See Also:
  - `ExecutorConfigurationSupport.initiateShutdown()`