flistell/poc-java-threadpools

Sample webservice to study the varius method one can parallelize works via thread pools in Java EE applications

★ 0Forks 0JavaGitHub ↗Compare

README

Thread Pools PoC - Java EE Worker Thread Management

DISCLAIMER:

This is sample code. Not for production use. It's available without any kind of support or certification, neither from me nor from the company I'm working at the moment.

Overview

This proof-of-concept demonstrates various approaches to managing worker threads and concurrent task execution in Java EE applications. It explores different thread pool strategies for handling application workloads efficiently.

Purpose

The project samples how to use various worker thread management techniques:

  1. Standard Java Thread Pools - Executors.newFixedThreadPool() for custom pool management
  2. Async Operations - CompletableFuture.supplyAsync() leveraging ForkJoinPool
  3. Container-Managed Executors - ManagedExecutorService for Java EE application-managed threading

Use Cases

  • Understanding thread pool behavior under load
  • Comparing custom vs. container-managed thread pools
  • Learning concurrent task execution patterns in Java EE
  • Observing thread allocation and task queuing in application servers

Quick Start

Build

mvn clean package

Deploy

Copy target/threadpools-0.0.1-SNAPSHOT.war to your Java EE application server (e.g., WebLogic autodeploy directory).

Test Endpoints

# Custom thread pool with Runnable tasks
curl "http://localhost:7001/threadpools/newthreadpool/runnableTasks?size=5&tasks=10"

# Custom thread pool with Callable tasks (returns results)
curl "http://localhost:7001/threadpools/newthreadpool/callableTasks?size=5&tasks=10"

# Async execution using CompletableFuture
curl "http://localhost:7001/threadpools/newthreadpool/completableFuture?tasks=10"

# Container-managed executor (Java EE)
curl "http://localhost:7001/threadpools/newthreadpool/managedExecutor?tasks=10"

Thread Pool Comparison

Approach Thread Management Use Case Pros Cons
Executors.newFixedThreadPool() Application-managed Simple, portable Full control Manual management, not container-aware
CompletableFuture.supplyAsync() ForkJoinPool Async/non-blocking Clean API, composability Uses common pool by default
ManagedExecutorService Java EE container-managed Standard Java EE Portable, lifecycle integration Requires Java EE server

WebLogic WorkManager Integration

For production deployments on WebLogic, use WorkManagers for advanced thread management with max/min constraints, fair sharing, and response time goals.

Quick Configuration (Recommended)

Create src/main/webapp/WEB-INF/weblogic.xml:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">

    <!-- Thread Constraints -->
    <max-threads-constraint>
        <name>threadpool_max_threads</name>
        <count>20</count>
    </max-threads-constraint>

    <min-threads-constraint>
        <name>threadpool_min_threads</name>
        <count>5</count>
    </min-threads-constraint>

    <!-- Work Manager -->
    <work-manager>
        <name>ThreadPoolWorkManager</name>
        <max-threads-constraint-name>threadpool_max_threads</max-threads-constraint-name>
        <min-threads-constraint-name>threadpool_min_threads</min-threads-constraint-name>
    </work-manager>

    <!-- Managed Executor backed by WorkManager -->
    <managed-executor-service>
        <name>ThreadPoolManagedExecutor</name>
        <work-manager>ThreadPoolWorkManager</work-manager>
    </managed-executor-service>
</weblogic-web-app>

Create src/main/webapp/WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0">
    <resource-env-ref>
        <resource-env-ref-name>concurrent/ThreadPoolExecutor</resource-env-ref-name>
        <resource-env-ref-type>javax.enterprise.concurrent.ManagedExecutorService</resource-env-ref-type>
    </resource-env-ref>
</web-app>

Update the service to use JNDI lookup:

private ManagedExecutorService getWorkManagerExecutor() {
    if (workManagerExecutor == null) {
        try {
            InitialContext ctx = new InitialContext();
            workManagerExecutor = (ManagedExecutorService) 
                ctx.lookup("concurrent/ThreadPoolExecutor");
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }
    return workManagerExecutor;
}

Alternative: Admin Console Configuration

  1. Login to WebLogic Console (http://localhost:7001/console)
  2. Navigate: Environment → Work Managers
  3. Create new Work Manager with constraints:
    • Max Threads: 20
    • Min Threads: 5
    • Fair Share: 100 (optional, for prioritization)

Monitoring

View WorkManager statistics in Admin Console: Environment → Servers → [Your Server] → Work Managers

Key metrics: Pending Requests, Completed Requests, Active Threads

Tuning Guidelines

Scenario Recommendation
High throughput Increase max-threads-constraint (50-100)
Guaranteed capacity Set min-threads-constraint to baseline load
Priority workloads Use fair-share (higher = more CPU time)
SLA requirements Use response-time-request-class with goal-ms

Note: Don't mix custom Executors with WorkManager-backed executors in the same application—this can cause resource contention.


Monitoring

Check server logs to observe thread names and task execution timing. The service logs:

  • Thread pool creation
  • Task start/end with thread names
  • Execution duration

For production debugging, thread dumps (like the included jstack.* file) help analyze thread pool behavior under load.


References


Contributors

flistell

Issues