Class VirtualThreadWorkerPool

java.lang.Object
express.mvp.myra.transport.VirtualThreadWorkerPool
All Implemented Interfaces:
AutoCloseable

public final class VirtualThreadWorkerPool extends Object implements AutoCloseable
High-performance worker pool using Java 21+ virtual threads for I/O event processing.

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

Virtual vs Platform Thread Guidelines
ScenarioRecommendation
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:
  • Method Details

    • builder

      public static VirtualThreadWorkerPool.Builder builder()
      Creates a new builder for configuring the worker pool.
      Returns:
      a new builder
    • create

      public static VirtualThreadWorkerPool create()
      Creates a worker pool with default settings.
      Returns:
      a new worker pool with default configuration
    • create

      public static VirtualThreadWorkerPool create(String namePrefix)
      Creates a worker pool with the given name prefix.
      Parameters:
      namePrefix - the prefix for worker thread names
      Returns:
      a new worker pool
    • submit

      public Future<?> submit(Runnable task)
      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

      public <T> Future<T> submit(Callable<T> task)
      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

      public void execute(Runnable task)
      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

      public boolean shutdown(Duration timeout) throws InterruptedException
      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

      public VirtualThreadWorkerPool.Stats getStats()
      Returns a snapshot of the pool's statistics.
      Returns:
      the current statistics
    • close

      public void close()
      Specified by:
      close in interface AutoCloseable
    • toString

      public String toString()
      Overrides:
      toString in class Object