From 5ee522598f6fdd94ac2a802f817f7e005445844b Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 20 Aug 2024 15:52:47 +0200 Subject: [PATCH] Explain that enabling virtual threads disables traditional thread pools Closes gh-41937 --- .../autoconfigure/task/TaskExecutionProperties.java | 12 +++++++----- .../autoconfigure/task/TaskSchedulingProperties.java | 3 ++- .../boot/autoconfigure/web/ServerProperties.java | 12 ++++++++---- .../docs/asciidoc/features/spring-application.adoc | 3 +++ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutionProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutionProperties.java index 9530f19828..0080213446 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutionProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutionProperties.java @@ -83,30 +83,32 @@ public class TaskExecutionProperties { /** * Queue capacity. An unbounded capacity does not increase the pool and therefore - * ignores the "max-size" property. + * ignores the "max-size" property. Doesn't have an effect if virtual threads are + * enabled. */ private int queueCapacity = Integer.MAX_VALUE; /** - * Core number of threads. + * Core number of threads. Doesn't have an effect if virtual threads are enabled. */ private int coreSize = 8; /** * Maximum allowed number of threads. If tasks are filling up the queue, the pool * can expand up to that size to accommodate the load. Ignored if the queue is - * unbounded. + * unbounded. Doesn't have an effect if virtual threads are enabled. */ private int maxSize = Integer.MAX_VALUE; /** * Whether core threads are allowed to time out. This enables dynamic growing and - * shrinking of the pool. + * shrinking of the pool. Doesn't have an effect if virtual threads are enabled. */ private boolean allowCoreThreadTimeout = true; /** - * Time limit for which threads may remain idle before being terminated. + * Time limit for which threads may remain idle before being terminated. Doesn't + * have an effect if virtual threads are enabled. */ private Duration keepAlive = Duration.ofSeconds(60); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskSchedulingProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskSchedulingProperties.java index ea26f32610..a3da30df05 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskSchedulingProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskSchedulingProperties.java @@ -63,7 +63,8 @@ public class TaskSchedulingProperties { public static class Pool { /** - * Maximum allowed number of threads. + * Maximum allowed number of threads. Doesn't have an effect if virtual threads + * are enabled. */ private int size = 1; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 03b794bb20..a8610bee0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -897,12 +897,14 @@ public class ServerProperties { public static class Threads { /** - * Maximum amount of worker threads. + * Maximum amount of worker threads. Doesn't have an effect if virtual threads + * are enabled. */ private int max = 200; /** - * Minimum amount of worker threads. + * Minimum amount of worker threads. Doesn't have an effect if virtual threads + * are enabled. */ private int minSpare = 10; @@ -1309,12 +1311,14 @@ public class ServerProperties { private Integer selectors = -1; /** - * Maximum number of threads. + * Maximum number of threads. Doesn't have an effect if virtual threads are + * enabled. */ private Integer max = 200; /** - * Minimum number of threads. + * Minimum number of threads. Doesn't have an effect if virtual threads are + * enabled. */ private Integer min = 8; diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc index feef506659..f617c67e64 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc @@ -387,6 +387,9 @@ If you're running on Java 21 or up, you can enable virtual threads by setting th Before turning on this option for your application, you should consider https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html[reading the official Java virtual threads documentation]. In some cases, applications can experience lower throughput because of "Pinned Virtual Threads"; this page also explains how to detect such cases with JDK Flight Recorder or the `jcmd` CLI. +NOTE: If virtual threads are enabled, properties which configure thread pools don't have an effect anymore. +That's because virtual threads are scheduled on a JVM wide platform thread pool and not on dedicated thread pools. + WARNING: One side effect of virtual threads is that they are daemon threads. A JVM will exit if all of its threads are daemon threads. This behavior can be a problem when you rely on `@Scheduled` beans, for example, to keep your application alive.