Chapter 24. Thread Management

Each JBoss EAP messaging server maintains a single thread pool for general use, and scheduled thread pool for scheduled use. A Java scheduled thread pool cannot be configured to use a standard thread pool, otherwise we could use a single thread pool for both scheduled and non scheduled activity.

Note that JBoss EAP uses the new, non-blocking NIO. By default, JBoss EAP messaging uses a number of threads equal to three times the number of cores, or hyper-threads, as reported by .getRuntime().availableProcessors() for processing incoming packets. To override this value, set the number of threads by specifying the nio-remoting-threads parameter in the transport configuration. See Configuring the Messaging Transports for more information.

24.1. Server Scheduled Thread Pool

The server scheduled thread pool is used for most activities on the server side that require running periodically or with delays. It maps internally to a java.util.concurrent.ScheduledThreadPoolExecutor instance.

The maximum number of thread used by this pool is configured using the scheduled-thread-pool-max-size parameter. The default value is 5 threads. A small number of threads is usually sufficient for this pool. To change this value for the default JBoss EAP messaging server, use the following management CLI command:

/subsystem=messaging-activemq/server=default:write-attribute(name=scheduled-thread-pool-max-size,value=10)

24.2. Server General Purpose Thread Pool

The general purpose thread pool is used for most asynchronous actions on the server side. It maps internally to a java.util.concurrent.ThreadPoolExecutor instance.

The maximum number of threads used by this pool is configured using the thread-pool-max-size attribute.

If thread-pool-max-size is set to -1, the thread pool has no upper bound and new threads are created on demand if there are not enough threads available to fulfill a request. If activity later subsides, then threads are timed out and closed.

If thread-pool-max-size is set to a positive integer greater than zero, the thread pool is bounded. If requests come in and there are no free threads available in the pool, requests will block until a thread becomes available. It is recommended that a bounded thread pool be used with caution since it can lead to deadlock situations if the upper bound is configured too low.

The default value for thread-pool-max-size is 30. To set a new value for the default JBoss EAP messaging server, use the following management CLI command.

/subsystem=messaging-activemq/server=default:write-attribute(name=thread-pool-max-size,value=40)

See the ThreadPoolExecutor Javadoc for more information on unbounded (cached), and bounded (fixed) thread pools.

24.3. Expiry Reaper Thread

A single thread is also used on the server side to scan for expired messages in queues. We cannot use either of the thread pools for this since this thread needs to run at its own configurable priority.

24.4. Asynchronous IO

Asynchronous IO has a thread pool for receiving and dispatching events out of the native layer. It is on a thread dump with the prefix ArtemisMQ-AIO-poller-pool. JBoss EAP messaging uses one thread per opened file on the journal (there is usually one).

There is also a single thread used to invoke writes on libaio. It is done to avoid context switching on libaio that would cause performance issues. This thread is found on a thread dump with the prefix ArtemisMQ-AIO-writer-pool.

24.5. Client Thread Management

JBoss EAP includes a client thread pool used for creating client connections. This pool is separate from the static pools mentioned earlier in this chapter and is used by JBoss EAP when it behaves like a client. For example, client thread pool clients are created as cluster connections with other nodes in the same cluster, or when the Artemis resource adapter connects to a remote Apache ActiveMQ Artemis messaging server integrated in a remote instance of JBoss EAP. There is a pool for scheduled client threads as well.

Note

With the release of JBoss EAP 7.1, client threads now timeout after 60 seconds of no activity.

Setting Client Thread Pool Size Using the Management CLI

Use the management CLI to configure the size of both the client thread pool and the client scheduled thread pool. Pool sizes set using the management CLI will have precedence over the sizings set using system properties.

The command below sets the client thread pool.

/subsystem=messaging-activemq:write-attribute(name=global-client-thread-pool-max-size,value=POOL_SIZE)

There is no default value defined for this attribute. If the attribute is not defined, the maximum size of the pool is determined to be eight (8) times the number of CPU core processors.

To review the current settings, use the following command.

/subsystem=messaging-activemq:read-attribute(name=global-client-thread-pool-max-size)

The client scheduled thread pool size is set using the following command.

/subsystem=messaging-activemq:write-attribute(name=global-client-scheduled-thread-pool-max-size,value=POOL_SIZE)

The following will display the current pool size for the client scheduled thread pool. The default value is 5.

/subsystem=messaging-activemq:read-attribute(name=global-client-scheduled-thread-pool-max-size)

Setting Client Thread Pool Size Using System Properties

The following system properties can be used to set the size of the client’s global and global scheduled thread pools respectively:

  • activemq.artemis.client.global.thread.pool.max.size
  • activemq.artemis.client.global.scheduled.thread.pool.core.size

The system properties can then be referenced in XML configuration, as in the example below.

Note

Pool sizes set using the management CLI will have precedence over sizes set by system properties.

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <global-client thread-pool-max-size="${activemq.artemis.client.global.thread.pool.max.size}"
    scheduled-thread-pool-max-size="${activemq.artemis.client.global.scheduled.thread.pool.core.size}" />
  <server ...>
  </server>
  ...
</subsystem>

Configuring a Client to Use Its Own Thread Pool

A client can configure each of its ClientSessionFactory instances to not use the pool provided by JBoss EAP, but instead to use its own client thread pool. Any sessions created from that ClientSessionFactory will use the newly created pool.

To configure a ClientSessionFactory instance to use its own pools, invoke the appropriate setter methods immediately after you created the factory. For example:

ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(transportConfiguration);
locator.setUseGlobalPools(true);
locator.setThreadPoolMaxSize(-1);
locator.setScheduledThreadPoolMaxSize(10);
ClientSessionFactory myFactory = locator.createSessionFactory();

If you are using the JMS API, you can set the same parameters on the ClientSessionFactory. For example:

ActiveMQConnectionFactory myConnectionFactory = ActiveMQJMSClient.createConnectionFactory(url, "ConnectionFactoryName");
myConnectionFactory.setUseGlobalPools(false);
myConnectionFactory.setScheduledThreadPoolMaxSize(10);
myConnectionFactory.setThreadPoolMaxSize(-1);

If you are using JNDI to instantiate ActiveMQConnectionFactory instances, you can also set these parameters using the management CLI, as in the examples given below for a standalone instance of JBoss EAP.

/subsystem=messaging-activemq/server=default/connection-factory=myConnectionFactory:write-attribute(name=use-global-pools,value=false)

/subsystem=messaging-activemq/server=default/connection-factory=myConnectionFactory:write-attribute(name=scheduled-thread-pool-max-size,value=10)

/subsystem=messaging-activemq/server=default/connection-factory=myConnectionFactory:write-attribute(name=thread-pool-max-size,value=1)

Note that the management CLI will remind you that a reload of the instance is required after you execute each of the above commands.