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.
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.
The project samples how to use various worker thread management techniques:
- Standard Java Thread Pools -
Executors.newFixedThreadPool()for custom pool management - Async Operations -
CompletableFuture.supplyAsync()leveraging ForkJoinPool - Container-Managed Executors -
ManagedExecutorServicefor Java EE application-managed threading
- 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
mvn clean packageCopy target/threadpools-0.0.1-SNAPSHOT.war to your Java EE application server (e.g., WebLogic autodeploy directory).
# 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"| 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 |
For production deployments on WebLogic, use WorkManagers for advanced thread management with max/min constraints, fair sharing, and response time goals.
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;
}- Login to WebLogic Console (
http://localhost:7001/console) - Navigate: Environment → Work Managers
- Create new Work Manager with constraints:
- Max Threads:
20 - Min Threads:
5 - Fair Share:
100(optional, for prioritization)
- Max Threads:
View WorkManager statistics in Admin Console: Environment → Servers → [Your Server] → Work Managers
Key metrics: Pending Requests, Completed Requests, Active Threads
| 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.
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.
- Oracle Docs: Using Work Managers to Optimize Scheduled Work
- Oracle Docs: Work Managers and Threading
- Oracle Docs: Configuring Work Managers