Class VirtualThreadWorkerPool
- All Implemented Interfaces:
AutoCloseable
This worker pool leverages Project Loom's virtual threads to handle millions of concurrent tasks with minimal overhead. Unlike traditional thread pools that are constrained by OS thread limits, virtual threads provide near-unlimited concurrency suitable for I/O-bound workloads.
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ VirtualThreadWorkerPool │
├─────────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ VThread-1 │ │ VThread-2 │ │ VThread-N │ ... │
│ │ (callback) │ │ (callback) │ │ (callback) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────────────┼─────────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ Work Queue │ (bounded or unbounded) │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ Carrier Thread Pool │
│ (ForkJoinPool.commonPool() default) │
└───────────────────────────────────────┘
Key Features
- Lightweight: Virtual threads use ~1KB stack vs ~1MB for platform threads
- High concurrency: Millions of concurrent tasks without OS limits
- Blocking-friendly: Blocking operations yield to carrier, don't waste resources
- Graceful shutdown: Configurable timeout for pending tasks
- Metrics: Track submitted, completed, and active tasks
When to Use Virtual Threads
| Scenario | Recommendation |
|---|---|
| I/O-bound callbacks | ✅ Virtual threads |
| Blocking network calls | ✅ Virtual threads |
| CPU-intensive compute | ❌ Platform threads (dedicated cores) |
| io_uring poll loop | ❌ Platform thread (pinned to core) |
| Synchronized locks (long-held) | ⚠️ Consider platform threads |
Usage Example
// Create worker pool for callback processing
VirtualThreadWorkerPool workers = VirtualThreadWorkerPool.builder()
.namePrefix("transport-worker")
.build();
// Submit callbacks from I/O completion handler
backend.poll((token, result) -> {
workers.submit(() -> {
// Process completion on virtual thread
// Blocking here is fine - yields to carrier
handler.onComplete(token, result);
});
});
// Graceful shutdown with timeout
workers.shutdown(Duration.ofSeconds(5));
Thread Safety
This class is thread-safe. Tasks can be submitted from any thread concurrently.
Memory Model
Task submission establishes a happens-before relationship with task execution.
All writes before submit(Runnable) are visible to the task.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classBuilder for creatingVirtualThreadWorkerPoolinstances.static final recordImmutable snapshot of worker pool statistics. -
Method Summary
Modifier and TypeMethodDescriptionbuilder()Creates a new builder for configuring the worker pool.voidclose()static VirtualThreadWorkerPoolcreate()Creates a worker pool with default settings.static VirtualThreadWorkerPoolCreates a worker pool with the given name prefix.voidExecutes a task without returning a Future.longReturns the approximate number of tasks currently being executed.longReturns the number of tasks that have completed successfully.longReturns the number of tasks that failed with an exception.longReturns the number of tasks rejected due to shutdown.getStats()Returns a snapshot of the pool's statistics.longReturns the number of tasks that have been submitted.longReturns the number of virtual threads created by this pool.booleanReturns whether this pool has been shut down.booleanReturns whether all tasks have completed following shutdown.booleanInitiates an orderly shutdown where previously submitted tasks are executed, but no new tasks will be accepted.voidAttempts to stop all actively executing tasks and halts processing of waiting tasks.Future<?> Submits a task for execution on a virtual thread.<T> Future<T> Submits a callable task for execution on a virtual thread.toString()
-
Method Details
-
builder
Creates a new builder for configuring the worker pool.- Returns:
- a new builder
-
create
Creates a worker pool with default settings.- Returns:
- a new worker pool with default configuration
-
create
Creates a worker pool with the given name prefix.- Parameters:
namePrefix- the prefix for worker thread names- Returns:
- a new worker pool
-
submit
Submits a task for execution on a virtual thread.The task will be executed asynchronously on a new virtual thread. If the pool has been shut down, the task is rejected and a warning is logged.
- Parameters:
task- the task to execute- Returns:
- a Future representing the pending completion, or null if rejected
- Throws:
NullPointerException- if task is null
-
submit
Submits a callable task for execution on a virtual thread.- Type Parameters:
T- the result type- Parameters:
task- the task to execute- Returns:
- a Future representing the pending result, or null if rejected
- Throws:
NullPointerException- if task is null
-
execute
Executes a task without returning a Future.This is a fire-and-forget method. If you need to track completion, use
submit(Runnable)instead.- Parameters:
task- the task to execute- Throws:
NullPointerException- if task is null
-
shutdown
Initiates an orderly shutdown where previously submitted tasks are executed, but no new tasks will be accepted.Invocation has no additional effect if already shut down.
- Parameters:
timeout- maximum time to wait for tasks to complete- Returns:
- true if all tasks completed before timeout, false otherwise
- Throws:
InterruptedException- if interrupted while waiting
-
shutdownNow
public void shutdownNow()Attempts to stop all actively executing tasks and halts processing of waiting tasks.This method does not wait for tasks to terminate. Use
shutdown(Duration)for graceful shutdown. -
isShutdown
public boolean isShutdown()Returns whether this pool has been shut down.- Returns:
- true if shutdown has been initiated
-
isTerminated
public boolean isTerminated()Returns whether all tasks have completed following shutdown.- Returns:
- true if terminated
-
getSubmittedTasks
public long getSubmittedTasks()Returns the number of tasks that have been submitted.- Returns:
- the submitted task count
-
getCompletedTasks
public long getCompletedTasks()Returns the number of tasks that have completed successfully.- Returns:
- the completed task count
-
getFailedTasks
public long getFailedTasks()Returns the number of tasks that failed with an exception.- Returns:
- the failed task count
-
getRejectedTasks
public long getRejectedTasks()Returns the number of tasks rejected due to shutdown.- Returns:
- the rejected task count
-
getActiveTasks
public long getActiveTasks()Returns the approximate number of tasks currently being executed.- Returns:
- the active task count
-
getThreadCount
public long getThreadCount()Returns the number of virtual threads created by this pool.- Returns:
- the thread count
-
getStats
Returns a snapshot of the pool's statistics.- Returns:
- the current statistics
-
close
public void close()- Specified by:
closein interfaceAutoCloseable
-
toString
-