ScheduledExecutorService CPU Spikes to 100% Due to Thread Pool Bug

When using ScheduledExecutorService with a core pool size of 0, a JDK bug can cause CPU usage to spike to 100%. This occurs due to an infinite loop in the getTask method of ThreadPoolExecutor when keepAliveTime is set to 0 nanoseconds.

Problem Demonstration

public static void main(String[] args) {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(0);
    executor.schedule(() -> {
        System.out.println("Business logic");
    }, 60, TimeUnit.SECONDS);
    executor.shutdown();
}

This code creates a thread pool with 0 core threads. The scheduled task runs after 60 seconds, but during this period, CPU usage spikes to 100%.

Root Cause

The issue stems from ThreadPoolExecutor.getTask():

  1. When corePoolSize = 0, timed becomes true (since wc > corePoolSize).
  2. The method calls workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) with keepAliveTime = 0.
  3. This creates a tight loop where the thread continuously checks for new tasks.

JDK Fix

The bug was fixed in JDK 9 by changing the default keepAliveTime from 0 nanoseconds to 10 milliseconds (DEFAULT_KEEPALIVE_MILLIS). This prevents the infinite loop scenario.

Another Related Bug (JDK-8051859)

When using scheduleWithFixedDelay with extremely large delays (e.g., Long.MAX_VALUE microseconds), the calculasion overflows, causing the next execution time to be set to 292 years in the past. The fix modifies the time calculation to avoid overflow.

Key Takeaways

  • Avoid setting corePoolSize = 0 in ScheduledExecutorService.
  • Be cautious with extremely large delay values in scheduled tasks.
  • The bugs were addressed in JDK 9, so upgrading may resolve these issues.

Tags: java ThreadPool ScheduledExecutorService JDK Performance

Posted on Thu, 04 Jun 2026 19:18:20 +0000 by skhale