Class Executors

java.lang.Object
ubic.gemma.core.util.concurrent.Executors

public class Executors extends Object
Extends Executors to ensure that security context logging works as expected.

All executors produced by this class will be wrapped with the following:

Author:
poirigui
  • Constructor Details

    • Executors

      public Executors()
  • Method Details

    • newSingleThreadExecutor

      public static ExecutorService newSingleThreadExecutor()
    • newSingleThreadExecutor

      public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
    • newFixedThreadPool

      public static ExecutorService newFixedThreadPool(int numThreads)
    • newFixedThreadPool

      public static ExecutorService newFixedThreadPool(int numThreads, ThreadFactory threadFactory)
    • newCachedThreadPool

      public static ExecutorService newCachedThreadPool()
    • newSingleThreadScheduledExecutor

      public static ScheduledExecutorService newSingleThreadScheduledExecutor()
    • newVirtualThreadPerTaskExecutorIfAvailable

      public static ExecutorService newVirtualThreadPerTaskExecutorIfAvailable()
      Returns a virtual-thread-per-task executor when running on a JVM that supports it (JDK 21+), or a cached thread pool fallback on older JVMs (JDK 17).

      This is a forward-prep factory: callsites that are I/O-bound (network fetchers, FTP/HTTP downloaders, REST clients, ontology updaters, parser readers) can opt in to virtual threads one at a time without each callsite needing to know about the running JDK version. CPU-bound workloads (ComBat, differential-expression analysis, math-heavy stats) should keep using newFixedThreadPool(int) or newCachedThreadPool() — virtual threads provide no throughput benefit there and add overhead.

      The returned executor is wrapped with the same security context + log4j ThreadContext delegation as every other factory in this class, so MDC and SecurityContext propagation work identically whether the underlying carrier is virtual or platform.

      Detection is via reflection on java.util.concurrent.Executors#newVirtualThreadPerTaskExecutor, which compiles cleanly on JDK 17 because the symbol is resolved at runtime, not compile time.

      Active callsites (JDK 21 migration): TaskRunningServiceImpl background-tasks executor, ServiceBeansConfig#expressionDataFileTaskExecutor, OntologyConfig#ontologyTaskExecutor, plus the earlier I/O-bound sites already on this factory. Further migration should continue per-callsite after auditing for synchronized blocks that hold the carrier thread (a known virtual-thread pitfall; prefer java.util.concurrent.locks.ReentrantLock in long-pinned regions).

      Returns:
      a ExecutorService backed by virtual threads on JDK 21+, otherwise by a cached platform thread pool; in both cases wrapped for security + thread context propagation.