6 ms·
> Hint, virtual threads in the same thread will all block if you use blocking IO. This is apparently not the case in the new JDK implementation of virtual thre
by mwcampbell 4y ago
> Hint, virtual threads in the same thread will all block if you use blocking IO.
This is apparently not the case in the new JDK implementation of virtual threads. According to JEP 425 (linked in the OP):
> Application code in the thread-per-request style can run in a virtual thread for the entire duration of a request, but the virtual thread consumes an OS thread only while it performs calculations on the CPU. The result is the same scalability as the asynchronous style, except it is achieved transparently: When code running in a virtual thread calls a blocking I/O operation in the java.* API, the runtime performs a non-blocking OS call and automatically suspends the virtual thread until it can be resumed later. To Java developers, virtual threads are simply threads that are cheap to create and almost infinitely plentiful. Hardware utilization is close to optimal, allowing a high level of concurrency and, as a result, high throughput, while the application remains harmonious with the multithreaded design of the Java Platform and its tooling.
So new Java virtual threads really are meaningfully different from Kotlin coroutines.
- jillesvangurp 4y agoNice. With Loom, you have to use a thing called continuations, which includes a method called suspend. So, under the hood, it does very much the same thing as Kotlin does with its suspend functions. Which isn't surprising if you understand how light weight/green thread schedulers work. Basically, you allow each "thread" to run until it suspends in some kind of loop. What Loom likely does for blocking IO is implement some continuation wrappers around that do the right thing; which is indeed nice. With Kotlin co-routines, you'd mostly avoid using blocking IO in favor of using non blocking IO. With the exception of legacy code that uses blocking IO which up until now you'd simply park on a threaded co-routine context for that reason. So, yes this is a very nice feature that I wasn't aware of and thanks for pointing that out. It won't massively change my life because there's not a whole lot of blocking IO happening in most things that I use. But it's great for transitioning legacy code to more modern frameworks without a lot of invasive changes.
- mwcampbell 4y agoAs I understand it, the point of Loom/virtual threads (same thing) is that blocking APIs, the kind that you can easily debug, profile, and otherwise use with standard JVM tooling, shouldn't be "legacy". Loom fixes the scaling problem so we can go back to doing things the older, simpler, now better way. In time, the explicitly non-blocking APIs, and Kotlin's compiler-based coroutines, will be legacy.
- adra 4y agoAfter recently taking on a relatively hefty Kotlin coroutine project for the express purpose of dealing with many suspends from io, I can say coroutines is pretty good at what it does. There are things that loom does better that I've been waiting years to get back into the JVM, but there are facets of coroutines that are just really straight forward that simply green threads can't easily resolve. My hope is that the java and Kotlin crews take the best of both worlds and create some.compelling frameworks, because in the end, a better set of products is good for everyone. Q
- seer-zig 4y ago> but there are facets of coroutines that are just really straight forward that simply green threads can't easily resolve Could you elaborate on some of those?
- gavinray 4y agoThe primary difference between Loom's virtual threads and Kotlin's virtual threads (coroutines) are: - Coroutines have a higher overhead. Though not huge, Loom threads are nearly free. - Kotlin Coroutines aren't pre-emptible (and this is the big one). Loom's threads are pre-emptible. This property is why they can be more efficient.
- mwcampbell 4y agoWhat I read in JEP 425 is that Loom threads aren't actually preempted by the JVM's user-space scheduler. They can be mapped onto an arbitrary number of OS threads, but if you use an OS thread per core, and one of your virtual threads is CPU-bound, it won't be preempted IIUC.
- jillesvangurp 4y agoFrom the spec "they are preempted when they block on I/O or synchronization.". That's nice but if you write some inefficient loop, your virtual thread won't be pre-empted. Also, Kotlin co-routines will obviously use Loom when it is available and offer the same benefits. All that takes is a few tweaks in the co-routines library. Mostly, that should not even be needed because Loom is API compatible with the old threadpool and thread APIs which already have extension functions to turn them into coroutine scopes. So, a lot of stuff should just benefit from Loom just by upgrading the JVM. Which is great of course.