Motivation: Trying to migrate Virtual Threads.
Problem: Even though Virtual Threads are cheap, OS may find it suspicious for some processes to be stacked up at the same time, like searching for IP or ports on the network.
I am using the below code to limit the creation of threads. TS_NetworkIPUtils TS_NetworkPortUtils
var executor = useVirtualThread
? Executors.newVirtualThreadPerTaskExecutor()
: Executors.newFixedThreadPool(MAX_THREAD_COUNT());
Is it possible to create an executor service for creating virtual threads and having a limiting feature at the same time?
tl;dr
Yes.
Pile up many virtual threads, blocked while waiting for a counting semaphore to be released by any of the limited number of currently-executing tasks.
Details
No, do not limit the number of threads. Virtual threads are by design extremely “cheap”, taking little in the way system resources (memory, CPU) by default. You likely can support millions of virtual threads at a time.
When your tasks are expensive, you may need to limit the amount of simultaneous tasks. Go ahead and stack up many threads, but block their execution to wait upon a certain number of concurrent tasks busy executing. Blocking on virtual threads is extremely cheap (their raison d’être), so no problem if they pile up.
Use a counting semaphore to limit simultaneous tasks
You can use a counting semaphore to limit the number of simultaneous tasks running in virtual threads. See section Rate Limiting in tutorial Virtual Threads by Cay Horstmann.
Something like the following example. We submit 15 tasks, but limit to only 5 or less executing simultaneously. The
new Semaphore ( 5 )provides a bucket of five permits that may acquired and released. The permits are like a total of five copies of a book being borrowed from a library and eventually returned for someone else to borrow — lots of borrowers, but only five at a time.Notice how the later tasks are waiting several seconds for a permit from our counting semaphore.
Finally, after all the submitted tasks are done, we exit our try-with-resources syntax block.
(Caveat: I just whipped out this code example, without much thought behind it. I was shooting for something simpler than the example seen in the linked Cay Horstmann tutorial.)
When run on Java 21 on a Mac with Apple Silicon from IntelliJ IDEA 2023.3.3 (Ultimate Edition).
For more info on virtual threads, see the fascinating video talks by Ron Pressler, Alan Bateman, or José Paumard. And read the JEP 444.