Skip to content

Commit 015beb0

Browse files
committed
Provide first-class virtual thread option for common executors
Closes gh-33807
1 parent 3732c71 commit 015beb0

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

Diff for: spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java

+27-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.springframework.context.Lifecycle;
3737
import org.springframework.context.SmartLifecycle;
3838
import org.springframework.context.event.ContextClosedEvent;
39+
import org.springframework.core.task.SimpleAsyncTaskExecutor;
40+
import org.springframework.core.task.VirtualThreadTaskExecutor;
3941
import org.springframework.lang.Nullable;
4042

4143
/**
@@ -75,6 +77,8 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
7577

7678
protected final Log logger = LogFactory.getLog(getClass());
7779

80+
private boolean virtualThreads = false;
81+
7882
private ThreadFactory threadFactory = this;
7983

8084
private boolean threadNamePrefixSet = false;
@@ -104,6 +108,25 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
104108
private volatile boolean lateShutdown;
105109

106110

111+
/**
112+
* Specify whether to use virtual threads instead of platform threads.
113+
* This is off by default, setting up a traditional platform thread pool.
114+
* <p>Set this flag to {@code true} on Java 21 or higher for a tightly
115+
* managed thread pool setup with virtual threads. In contrast to
116+
* {@link SimpleAsyncTaskExecutor}, this is integrated with Spring's
117+
* lifecycle management for stopping and restarting execution threads,
118+
* including an early stop signal for a graceful shutdown arrangement.
119+
* <p>Specify either this or {@link #setThreadFactory}, not both.
120+
* @since 6.2
121+
* @see #setThreadFactory
122+
* @see VirtualThreadTaskExecutor#getVirtualThreadFactory()
123+
* @see SimpleAsyncTaskExecutor#setVirtualThreads
124+
*/
125+
public void setVirtualThreads(boolean virtualThreads) {
126+
this.virtualThreads = virtualThreads;
127+
this.threadFactory = this;
128+
}
129+
107130
/**
108131
* Set the ThreadFactory to use for the ExecutorService's thread pool.
109132
* The default is the underlying ExecutorService's default thread factory.
@@ -120,6 +143,7 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
120143
*/
121144
public void setThreadFactory(@Nullable ThreadFactory threadFactory) {
122145
this.threadFactory = (threadFactory != null ? threadFactory : this);
146+
this.virtualThreads = false;
123147
}
124148

125149
@Override
@@ -282,7 +306,9 @@ public void initialize() {
282306
if (!this.threadNamePrefixSet && this.beanName != null) {
283307
setThreadNamePrefix(this.beanName + "-");
284308
}
285-
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
309+
ThreadFactory factory = (this.virtualThreads ?
310+
new VirtualThreadTaskExecutor(getThreadNamePrefix()).getVirtualThreadFactory() : this.threadFactory);
311+
this.executor = initializeExecutor(factory, this.rejectedExecutionHandler);
286312
this.lifecycleDelegate = new ExecutorLifecycleDelegate(this.executor);
287313
}
288314

0 commit comments

Comments
 (0)