7 min read

(For more resources related to this topic, see here.)

In a high-performance environment, every costly resource instantiation needs to be minimized. This can be done effectively using pools. The different subsystems in WildFly often use various pools of resources to minimize the cost of creating new ones. These resources are often threads or various connection objects. Another benefit is that the pools work as a gatekeeper, hindering the underlying system from being overloaded. This is performed by preventing client calls from reaching their target if a limit has been reached.

In the upcoming sections of this article, we will provide an overview of the different subsystems and their pools.

The thread pool executor subsystem

The thread pool executor subsystem was introduced in JBoss AS 7. Other subsystems can reference thread pools configured in this one. This makes it possible to normalize and manage the thread pools via native WildFly management mechanisms, and it allows you to share thread pools across subsystems.

The following code is an example taken from the WildFly Administration Guide (https://docs.jboss.org/author/display/WFLY8/Admin+Guide) that describes how the Infinispan subsystem may use the subsystem, setting up four different pools:

<subsystem > <thread-factory name=”infinispan-factory” priority=”1″/> <bounded-queue-thread-pool name=”infinispan-transport”> <core-threads count=”1″/> <queue-length count=”100000″/> <max-threads count=”25″/> <thread-factory name=”infinispan-factory”/> </bounded-queue-thread-pool> <bounded-queue-thread-pool name=”infinispan-listener”> <core-threads count=”1″/> <queue-length count=”100000″/> <max-threads count=”1″/> <thread-factory name=”infinispan-factory”/> </bounded-queue-thread-pool> <scheduled-thread-pool name=”infinispan-eviction”> <max-threads count=”1″/> <thread-factory name=”infinispan-factory”/> </scheduled-thread-pool> <scheduled-thread-pool name=”infinispan-repl-queue”> <max-threads count=”1″/> <thread-factory name=”infinispan-factory”/> </scheduled-thread-pool> </subsystem> … <cache-container name=”web” default-cache=”repl”listener-executor=
“infinispan-listener” eviction-executor=
“infinispan-eviction”replication-queue-executor
=”infinispan-repl-queue”> <transport executor=”infinispan-transport”/> <replicated-cache name=”repl” mode=”ASYNC” batching=”true”> <locking isolation=”REPEATABLE_READ”/> <file-store/> </replicated-cache> </cache-container>


The following thread pools are available:

  • unbounded-queue-thread-pool
  • bounded-queue-thread-pool
  • blocking-bounded-queue-thread-pool
  • queueless-thread-pool
  • blocking-queueless-thread-pool
  • scheduled-thread-pool

The details of these thread pools are described in the following sections:

unbounded-queue-thread-pool

The unbounded-queue-thread-pool thread pool executor has the maximum size and an unlimited queue. If the number of running threads is less than the maximum size when a task is submitted, a new thread will be created. Otherwise, the task is placed in a queue. This queue is allowed to grow infinitely.

The configuration properties are shown in the following table:

max-threads

Max allowed threads running simultaneously

keepalive-time

This specifies the amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

thread-factory

This specifies the thread factory to use to create worker threads.

bounded-queue-thread-pool

The bounded-queue-thread-pool thread pool executor has a core, maximum size, and a specified queue length. If the number of running threads is less than the core size when a task is submitted, a new thread will be created; otherwise, it will be put in the queue. If the queue’s maximum size has been reached and the maximum number of threads hasn’t been reached, a new thread is also created. If max-threads is hit, the call will be sent to the handoff-executor. If no handoff-executor is configured, the call will be discarded.

The configuration properties are shown in the following table:

core-threads

Optional and should be less that max-threads

queue-length

This specifies the maximum size of the queue.

max-threads

This specifies the maximum number of threads that are allowed to run simultaneously.

keepalive-time

This specifies the amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

Handoff-executor

This specifies an executor to which tasks will be delegated, in the event that a task cannot be accepted.

allow-core-timeout

This specifies whether core threads may time-out; if false, only threads above the core size will time-out.

thread-factory

This specifies the thread factory to use to create worker threads.

blocking-bounded-queue-thread-pool

The blocking-bounded-queue-thread-pool thread pool executor has a core, a maximum size and a specified queue length. If the number of running threads is less than the core size when a task is submitted, a new thread will be created. Otherwise, it will be put in the queue. If the queue’s maximum size has been reached, a new thread is created; if not, max-threads is exceeded. If so, the call is blocked.

The configuration properties are shown in the following table:

core-threads

Optional and should be less that max-threads

queue-length

This specifies the maximum size of the queue.

max-threads

This specifies the maximum number of simultaneous threads allowed to run.

keepalive-time

This specifies the amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

allow-core-timeout

This specifies whether core threads may time-out; if false, only threads above the core size will time-out.

thread-factory

This specifies the thread factory to use to create worker threads

queueless-thread-pool

The queueless-thread-pool thread pool is a thread pool executor without any queue. If the number of running threads is less than max-threads when a task is submitted, a new thread will be created; otherwise, the handoff-executor will be called. If no handoff-executor is configured the call will be discarded.

The configuration properties are shown in the following table:

max-threads

Max allowed threads running simultaneously

keepalive-time

The amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

handoff-executor

Specifies an executor to delegate tasks to in the event that a task cannot be accepted

thread-factory

The thread factory to use to create worker threads

blocking-queueless-thread-pool

The blocking-queueless-thread-pool thread pool executor has no queue. If the number of running threads is less than max-threads when a task is submitted, a new thread will be created. Otherwise, the caller will be blocked.

The configuration properties are shown in the following table:

max-threads

Max allowed threads running simultaneously

keepalive-time

This specifies the amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

thread-factory

This specifies the thread factory to use to create worker threads

scheduled-thread-pool

The scheduled-thread-pool thread pool is used by tasks that are scheduled to trigger at a certain time.

The configuration properties are shown in the following table:

max-threads

Max allowed threads running simultaneously

keepalive-time

This specifies the amount of time that pool threads should be kept running when idle. (If not specified, threads will run until the executor is shut down.)

thread-factory

This specifies the thread factory to use to create worker threads

Monitoring

All of the pools just mentioned can be administered and monitored using both CLI and JMX (actually, the Admin Console can be used to administer, but not see, any live data). The following example and screenshots show the access to an unbounded-queue-thread-pool called test.

Using CLI, run the following command:

/subsystem=threads/unbounded-queue-thread-pool=test:read-resource
(include-runtime=true)


The response to the preceding command is as follows:

{ “outcome” => “success”, “result” => { “active-count” => 0, “completed-task-count” => 0L, “current-thread-count” => 0, “keepalive-time” => undefined, “largest-thread-count” => 0, “max-threads” => 100, “name” => “test”, “queue-size” => 0, “rejected-count” => 0, “task-count” => 0L, “thread-factory” => undefined } }


Using JMX (query and result in the JConsole UI), run the following code:

jboss.as:subsystem=threads,unbounded-queue-thread-pool=test


An example thread pool by JMX is shown in the following screenshot:

An example thread pool by JMX

The following screenshot shows the corresponding information in the Admin Console

Example thread pool—Admin Console

The future of the thread subsystem

According to the official JIRA case WFLY-462 (https://issues.jboss.org/browse/WFLY-462), the central thread pool configuration has been targeted for removal in future versions of the application server. It is, however, uncertain that all subprojects will adhere to this. The actual configuration will then be moved out to the subsystem itself. This seems to be the way the general architecture of WildFly is moving in terms of pools—moving away from generic ones and making them subsystem-specific. The different types of pools described here are still valid though.

Note that, contrary to previous releases, Stateless EJB is no longer pooled by default. More information of this is available in the JIRA case WFLY-1383. It can be found at https://issues.jboss.org/browse/WFLY-1383.

LEAVE A REPLY

Please enter your comment!
Please enter your name here