Earlier constructs that are not or not always preemptive, such as coroutines, green threads or the largely single-threaded Node.js, introduce delays in responding to asynchronous events such as every incoming request in a server application.
Java servers have featured extensive and memory consuming software constructs allowing dozens of pooled operating system threads to preemptively execute thousands of requests per second without the use of virtual threads.
In 2021, a consumer grade computers typically offer a parallelism of tens of concurrent execution units.
The maximum number of threads possible without swapping is proportional to the amount of main memory.
[15] Because virtual threads offer parallelism, the programmer needs to be skilled in multi-threaded programming and synchronization.