2222import java .io .OutputStreamWriter ;
2323import java .io .PrintWriter ;
2424import java .io .Serializable ;
25+ import java .lang .Thread .Builder .OfVirtual ;
2526import java .lang .reflect .Constructor ;
2627import java .net .URL ;
2728import java .nio .charset .StandardCharsets ;
4243import java .util .concurrent .CopyOnWriteArrayList ;
4344import java .util .concurrent .Executor ;
4445import java .util .concurrent .ExecutorService ;
46+ import java .util .concurrent .Executors ;
4547import java .util .concurrent .Future ;
46- import java .util .concurrent .LinkedBlockingQueue ;
4748import java .util .concurrent .ThreadFactory ;
48- import java .util .concurrent .ThreadPoolExecutor ;
4949import java .util .concurrent .TimeUnit ;
50- import java .util .concurrent .atomic .AtomicInteger ;
5150import java .util .concurrent .locks .Lock ;
5251import java .util .concurrent .locks .ReentrantLock ;
5352import java .util .stream .Collectors ;
@@ -609,13 +608,8 @@ public Instantiator getInstantiator() {
609608 }
610609
611610 /**
612- * Creates a default executor instance to use with this service.
613- * <p>
614- * This default implementation creates a thread pool executor with a custom
615- * thread factory to generate daemon threads. It uses a core pool size of 8,
616- * an unbounded maximum pool size, and a keep-alive time of 60 seconds for
617- * idle threads. The thread pool grows dynamically as required, and idle
618- * core threads are allowed to time out.
611+ * Creates a default executor instance to use with this service. This
612+ * default implementation creates a virtual tread executor.
619613 * <p>
620614 * A custom {@link VaadinService} implementation can override this method to
621615 * provide its own ad-hoc executor tailored to specific environments like
@@ -635,42 +629,17 @@ public Instantiator getInstantiator() {
635629 */
636630 protected Executor createDefaultExecutor () {
637631 this .defaultExecutorInUse = true ;
638- int corePoolSize = 8 ;
639- int keepAliveTimeSec = 60 ;
640-
641- class VaadinThreadFactory implements ThreadFactory {
642- private final AtomicInteger threadNumber = new AtomicInteger (0 );
632+ ThreadFactory namedVirtualThreadFactory = defaultExecutorFactory ()
633+ .factory ();
634+ return Executors .newThreadPerTaskExecutor (namedVirtualThreadFactory );
635+ }
643636
644- @ Override
645- public Thread newThread (Runnable runnable ) {
646- int threadNumber = this .threadNumber .incrementAndGet ();
647- if (threadNumber == 1 ) {
648- getLogger ().info (
649- "The application is using Vaadin's default ThreadPoolExecutor "
650- + "(pool size = {}, keep alive time = {} seconds). "
651- + "A custom executor with an appropriate thread pool "
652- + "can be provided registering a {}." ,
653- corePoolSize , keepAliveTimeSec ,
654- VaadinServiceInitListener .class .getSimpleName ());
655- }
656- Thread thread = new Thread (runnable ,
657- "VaadinTaskExecutor-thread-" + threadNumber );
658- // Thread marked as daemon to prevent task execution to block
659- // JVM shutdown
660- thread .setDaemon (true );
661- thread .setPriority (Thread .NORM_PRIORITY );
662- return thread ;
663- }
664- }
665- // Defaults taken from Spring Boot configuration
666- // org.springframework.boot.autoconfigure.task.TaskExecutionProperties.Pool
667- ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor (
668- corePoolSize , Integer .MAX_VALUE , keepAliveTimeSec ,
669- TimeUnit .SECONDS , new LinkedBlockingQueue <>(),
670- new VaadinThreadFactory ());
671- // Enables dynamic growing and shrinking of the pool.
672- threadPoolExecutor .allowCoreThreadTimeOut (true );
673- return threadPoolExecutor ;
637+ /*
638+ * Package private to allow overriding with an uncaught exception handler in
639+ * tests
640+ */
641+ OfVirtual defaultExecutorFactory () {
642+ return Thread .ofVirtual ().name ("VaadinTaskExecutor-thread-" , 1 );
674643 }
675644
676645 /**
0 commit comments