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));
+    }
 }

Reply via email to