This is an automated email from the ASF dual-hosted git repository.
zrlw pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new d9a4f35698 feat: enhance VirtualThreadPool with configurable minimum
thread count (#16055)
d9a4f35698 is described below
commit d9a4f356987afb1f66e05dd1cae6e7f1b91f4d0b
Author: funkye <[email protected]>
AuthorDate: Wed Jan 28 13:18:58 2026 +0800
feat: enhance VirtualThreadPool with configurable minimum thread count
(#16055)
* feat: enhance VirtualThreadPool to support configurable thread pool size
* fix: update default thread count in VirtualThreadPool to zero
* feat: add VT_THREADS_KEY for virtual thread pool configuration
* refactor: rename VT_THREADS_KEY to THREADS_VIRTUAL_CORE for clarity
---
.../dubbo/common/constants/CommonConstants.java | 2 ++
.../threadpool/support/loom/VirtualThreadPool.java | 18 +++++++++++--
.../support/loom/VirtualThreadPoolTest.java | 30 ++++++++++++++++++++++
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index 50cc0a830c..d2cd352132 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -126,6 +126,8 @@ public interface CommonConstants {
String THREADS_KEY = "threads";
+ String THREADS_VIRTUAL_CORE = "threads.virtual.core";
+
String QUEUES_KEY = "queues";
String ALIVE_KEY = "alive";
diff --git
a/dubbo-plugin/dubbo-plugin-loom/src/main/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPool.java
b/dubbo-plugin/dubbo-plugin-loom/src/main/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPool.java
index 4e807991d6..bf9f01436e 100644
---
a/dubbo-plugin/dubbo-plugin-loom/src/main/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPool.java
+++
b/dubbo-plugin/dubbo-plugin-loom/src/main/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPool.java
@@ -21,8 +21,11 @@ import org.apache.dubbo.common.threadpool.ThreadPool;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
import static
org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREAD_NAME;
+import static
org.apache.dubbo.common.constants.CommonConstants.THREADS_VIRTUAL_CORE;
import static
org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;
/**
@@ -35,7 +38,18 @@ public class VirtualThreadPool implements ThreadPool {
public Executor getExecutor(URL url) {
String name =
url.getParameter(THREAD_NAME_KEY, (String)
url.getAttribute(THREAD_NAME_KEY, DEFAULT_THREAD_NAME));
- return Executors.newThreadPerTaskExecutor(
- Thread.ofVirtual().name(name, 1).factory());
+ int threads = url.getParameter(THREADS_VIRTUAL_CORE, 0);
+ if (threads > 0) {
+ return new ThreadPoolExecutor(
+ threads,
+ Integer.MAX_VALUE,
+ 0L,
+ java.util.concurrent.TimeUnit.MILLISECONDS,
+ new SynchronousQueue<>(),
+ Thread.ofVirtual().name(name, 1).factory());
+ } else {
+ return Executors.newThreadPerTaskExecutor(
+ Thread.ofVirtual().name(name, 1).factory());
+ }
}
}
diff --git
a/dubbo-plugin/dubbo-plugin-loom/src/test/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPoolTest.java
b/dubbo-plugin/dubbo-plugin-loom/src/test/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPoolTest.java
index beebc26f72..2f0ac0d916 100644
---
a/dubbo-plugin/dubbo-plugin-loom/src/test/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPoolTest.java
+++
b/dubbo-plugin/dubbo-plugin-loom/src/test/java/org/apache/dubbo/common/threadpool/support/loom/VirtualThreadPoolTest.java
@@ -21,6 +21,8 @@ import org.apache.dubbo.common.threadpool.ThreadPool;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
@@ -28,8 +30,10 @@ import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import static org.apache.dubbo.common.constants.CommonConstants.QUEUES_KEY;
+import static
org.apache.dubbo.common.constants.CommonConstants.THREADS_VIRTUAL_CORE;
import static
org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -64,4 +68,30 @@ public class VirtualThreadPoolTest {
threadPool.getExecutor(url).getClass().getName(),
Matchers.is("java.util.concurrent.ThreadPerTaskExecutor"));
}
+
+ @Test
+ @EnabledForJreRange(min = JRE.JAVA_21)
+ void getExecutor3() throws Exception {
+ URL url = URL.valueOf(
+ "dubbo://10.20.130.230:20880/context/path?" +
THREADS_VIRTUAL_CORE + "=2&" + THREAD_NAME_KEY + "=demo");
+ ThreadPool threadPool = new VirtualThreadPool();
+ Executor executor = threadPool.getExecutor(url);
+
+ assertThat(executor, instanceOf(ThreadPoolExecutor.class));
+ ThreadPoolExecutor tpe = (ThreadPoolExecutor) executor;
+ assertThat(tpe.getCorePoolSize(), is(2));
+ assertThat(tpe.getMaximumPoolSize(), is(Integer.MAX_VALUE));
+ assertThat(tpe.getQueue(), instanceOf(SynchronousQueue.class));
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ executor.execute(() -> {
+ Thread thread = Thread.currentThread();
+ assertTrue(thread.isVirtual());
+ assertThat(thread.getName(), startsWith("demo"));
+ latch.countDown();
+ });
+
+ latch.await();
+ assertThat(latch.getCount(), is(0L));
+ }
}