ExecutorService.awaitTermination and virtual threads

Arkadiusz Gasiński jigga at jigga.pl
Mon Dec 9 17:29:33 UTC 2019


Hi,

I know loom's still in the prototyping phase but just wanted to share one
observation related to supplying custom scheduler/executor to virtual
thread factory.

The first example shows how I'm used to working with ExecutorService with
old Threads. The code is in Kotlin, but I hope that this does not distract
you from the point I'm trying to make (plus shows that Kotlin works with
the latest loom build).

fun main() {
    val task = Runnable {
        println("${Thread.currentThread().name} - Going to sleep for
10 seconds")
        TimeUnit.SECONDS.sleep(10)
        println("${Thread.currentThread().name} - Woke up after 10 seconds")
    }

    val threadScheduler = Executors.newCachedThreadPool()

    threadScheduler.submit(task)
    threadScheduler.submit(task)
    threadScheduler.submit(task)

    TimeUnit.SECONDS.sleep(1)
    threadScheduler.shutdown()
    threadScheduler.awaitTermination(15, TimeUnit.SECONDS)
}


The case here is that the *awaitTermination* method at the end of the main
waits until all submitted tasks complete, which is what I'm actually used
to.

Now, when I switch to virtual threads...

fun main() {
    val task = Runnable {
        println("${Thread.currentThread().name} - Going to sleep for
10 seconds")
        TimeUnit.SECONDS.sleep(10)
        println("${Thread.currentThread().name} - Woke up after 10 seconds")
    }

    val scheduler = Executors.newSingleThreadExecutor()
    val virtualThreadFactory =
Thread.builder().virtual().daemon(false).name("virtual-thread-",
1).factory()

    virtualThreadFactory.newThread(task).start()
    virtualThreadFactory.newThread(task).start()
    virtualThreadFactory.newThread(task).start()

    TimeUnit.SECONDS.sleep(1)
    scheduler.shutdown()
    scheduler.awaitTermination(10, TimeUnit.SECONDS)
}


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)?

Thanks,
Arek


More information about the loom-dev mailing list