ExecutorService.awaitTermination and virtual threads

Alan Bateman Alan.Bateman at oracle.com
Mon Dec 9 18:19:57 UTC 2019

On 09/12/2019 17:29, Arkadiusz Gasiński wrote:
> :
>      val scheduler = Executors.newSingleThreadExecutor()
>      val virtualThreadFactory =
> Thread.builder().virtual().daemon(false).name("virtual-thread-",
> 1).factory()
I assume you missing a call to the builder's scheduler method here as 
other this ThreadFactory will create virtual threads that are use the 
default scheduler.

> :
> The issue here is that now the awaitTermination method does not wait for
> all running virtual threads to finish. Correct me if I'm wrong, but I
> assume that this is due to the fact that this executor service is simply
> not aware of the running virtual threads (although the executor service
> serves as virtual thread scheduler, so maybe it's actually aware, in which
> case I have no clue why it behaves like this)?
Yes, the 3 virtual threads are blocked in Thread.sleep so there are no 
tasks running and the single work (carrier) thread is idle. This allows 
the thread pool to shutdown and terminate.

Once there are a few more pieces in place then it should be possible to 
do the following with the prototype:

         try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
             ThreadFactory factory = Thread.builder()
                     .name("virtual-thread-", 1)
             try (ExecutorService executor = 
Executors.newUnboundedExecutor(factory)) {
                 executor.submit(() -> {
                     String name = Thread.currentThread().getName();
                     System.out.format("%s going to sleep for 10 
seconds%n", name);
                     System.out.format("%s woke up after 10 seconds%n", 
                     return null;


More information about the loom-dev mailing list