Ron Pressler
cr.openjdk.java.net/~rpressler · Personal blog · on HN since 2017
Ron Pressler leads Project Loom at OpenJDK and writes on fibers, virtual threads, and continuations for the JVM.
What HN saysHN links his Loom documents when discussing lightweight threads, async/await, and tail calls on the JVM. Commenters mention him as the Quasar library's author.
40HN people shared it
31linked it in comments
11stories submitted
353story points
4 years agolast shared
2017people per year2026
Most-shared posts
- 1Project Loom: Fibers and Continuations for the Java Virtual Machine19 people · 126 points · first shared 2017 · 41 comments on HN
- 2State of Loom17 people · 225 points · first shared 2020 · 134 comments on HN
- 3State of Loom: Part 29 people · 2 points · first shared 2020 · discussion on HN
What HN people wrote when they linked it
ackfoobar · 2022-05-10
>> single kernel thread
> This is pretty much how JavaScript operates
> javascript has exactly 1 thread
No disagreement here.
I understand what you are saying. Would be great if you had tried to understand what I said.
Maybe my explanation is lacking. Let me quote pron.
> Again, threads — at least in this context — [...] refer only to the abstraction allowing programmers to write sequences of code that can run and pause.
https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html#header-…
An kernel thread running code line-by-line is a "thread"; callbacks that are sequenced (and have the dreaded pyramid indentation hell) forms a "thread"; when an async function is called there is also a "thread".
In JavaScript the latter two kinds of "threads" are run by one single kernel thread, i.e. N:1 threading.
thamer · 2020-09-21
For the JVM it's worth noting that Project Loom[1], while so far focused mainly on concurrency features like virtual threads and continuations also includes a proposal to implement better tail calls in the JVM:
> it is also the goal of this project to add an even lighter-weight construct that will allow unwinding the stack to some point and then invoke a method with given arguments (basically, a generalization of efficient tail-calls). We will call that feature unwind-and-invoke, or UAI. It is not the goal of this project to add an automatic tail-call optimization to the JVM.
Since this paragraph is explicit about the feature not being "automatic", it'll be interesting to see what form this takes.
[1] https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
kjeetgill · 2018-08-08
I agree it's always left a bag taste in my mouth. I loved generators and yield/yield from, but I was stuck on 2.7 for a long time so I never quite understood the motivation for async/await over them.
One issue is that it "reifys" the "colored function" problem that green threads like goroutines don't have!
Side note: Java world is working on green threads/fibers for the JVM in Project Loom.
[0]: http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
haglin · 2018-06-29
It may be worth mentioning that project Loom [1][2] aims to add continuations and lightweight threading to Java. It is lead by Ron Pressler, the author of the Quasar library mentioned in the paper.
Also, JDK 11 (Hotspot) comes with a new concurrent non-generational garbage collector (ZGC) [3] that has an average pause time of 1 ms [4]. It is still an experimental feature, but that will most likely change over time.
[1] http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
[2] http://openjdk.java.net/projects/loom/
[3] http://openjdk.java.net/jeps/333
[4] https://youtu.be/tShc0dyFtgw?t=4m58s
BenoitP · 2018-03-08
> libc is pretty shallow. The majority are either leaf functions like strlen(), or <5 levels from a leaf/before execution disappears into a system call.)
I'd wager that the JIT in OP's picture will transform that huge call stack into something <5 levels from CPU instructions/syscalls.
What remains though, is the huge context carried around such a stack; and I'm quite excited at what the Loom project [1] could yield to tackle that.
Such huge call stacks are a good sign to me. I don't want to implement all the corner cases of all the RFC I rely on; and it is great that library implementors can organise their code well. In the end the JIT will adapt my program to the currently used corner case, and prune everything else.
[1] http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
jp57 · 2022-05-14
I gotta say, as a programmer "of a certain age", a lot of recent advances have an everything-old-is-new-again feel to me. When I first heard of "threads" in the 90s, the term specifically referred to a mechanism for intra-process concurrency that was "lightweight", i.e. it didn't have the heavy overhead of forking a new OS process. IIRC they weren't even preemptively multitasked. Then preemptive "OS threads" became the new hotness and everything using cooperative threads was old and busted. Now a generation has passed and we have "virtual threads" or things like asyncio to solve the problems created by the thing that solved the problems of the thing before.
A similar thing has happened at the OS level with support for multiple programs. Computers started out running one program at a time. Then "multitasking" was invented, and along with it all kinds of things to make it safer and easier like users and permissions and protected memory, and it was great, many different users could run different programs on the same machine. Then we moved from running statically linked binary executables to dynamic linking and interpreted languages that load libraries at run time. Managing environments for different programs on one machine got hard. VMs and hypervisors let us segment a machine into virtual machines where the environments were easy to control. But VMs were a heavyweight solution for managing environments, so along came containers, which are kind of virtual virtual…
wahern · 2018-07-31
The best and most careful description of all these concepts in a single source is the Project Loom proposal: http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
Other than this paper, http://www.inf.puc-rio.br/~roberto/docs/corosblp.pdf, which revived interest in coroutines, I don't have links handy for authoritative sources in the academic literature regarding nomenclature. "Stackful" and "stackless" are relatively recent descriptions and not too long ago they could have meant the complete opposite--Stackless Python (http://www.stackless.com/spcpaper.htm) implements what would now be called stackful coroutines.[1] But I think it's fair to say that today there's a relatively fixed nomenclature about the concepts. But people still create unnecessary confusion by conflating implementation details (often coincidental or accidental) with the abstract concepts.
[1] The Stackless Python website talks about microthreads and tasklets, but the original paper begins the discussion with continuations, generators, and coroutines, and builds up from there.
kasperni · 2022-11-21
> Fibers have finally landed, about a decade later than promised, but the ecosystem hasn't even begun to adopt them yet and who knows what edge cases or issues may turn up.
First, Project Loom was announced in late 2017 [1]. So I don't really understand where you get that decade from? Second, it is available as a preview feature in latest JDK. Why would people adopt a preview feature in their production systems? A lot of frameworks have already added support or as a minimum started working on support for virtual threads. I'm sure all major frameworks will support them once they are out of preview.
[1] https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
papercrane · 2022-06-03
The "State of Loom" document from May 2020 discusses this sort of problem. Long-term I believe the solution is to allow preempting at any safe-point and custom schedulers, but neither of those will be delivered in the first preview.
https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html
Copenjin · 2022-05-13
For those wondering about the "tail call" part that would be more interesting for Clojure than fibers:
As adding the ability to manipulate call stacks to the JVM will undoubtedly be required, it is also the goal of this project to add an even lighter-weight construct that will allow unwinding the stack to some point and then invoke a method with given arguments (basically, a generalization of efficient tail-calls). We will call that feature unwind-and-invoke, or UAI.
It is not the goal of this project to add an automatic tail-call optimization to the JVM.
[1] https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
sdfgdfgbsdfg · 2022-04-30
pron talks about this on https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html#chann…
cafxx · 2022-02-20
You may want to look at project loom's virtual threads, that are designed to address almost exactly your problem:
https://openjdk.java.net/jeps/8277131
https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html
https://youtu.be/KG24inClY2M
azth · 2021-11-12
Check out structured concurrency proposal in Loom:
* https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html
* https://wiki.openjdk.java.net/display/loom/Getting+started
* https://wiki.openjdk.java.net/display/loom/Structured+Concurrency
capableweb · 2021-08-16
Is this the wiki page you mean? https://wiki.openjdk.java.net/display/loom/Main Seems to also be lacking of content.
Tiny link on the right called "State of Loom" seems to have the most background information though, and should be helpful to people like me who had no idea what Loom is/supposed to be:
http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
samus · 2021-07-20
Project Loom's scope explicitly encompasses not only virtual threads. To do that, the concept of structured concurrency[1] was introduced. There /are/ going to be new APIs.
[1]: http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html
_old_dude_ · 2021-07-19
By the OS, not by the scheduler
see https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html#force…
vips7L · 2021-07-19
Unless I'm misunderstanding, virtual threads are preemptive: https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
mikepurvis · 2021-07-19
It sounds like it is: https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
But the other side of that is that sometimes non-preemption is also a desirable property— like in JavaScript, or Python asyncio, knowing that you don't need to lock over every little manipulation of some shared data structure because you're never going to yield if you didn't explicitly await.
jacques_chester · 2021-04-01
Briefly, that a thread cannot escape a scope. All threads must be joined before leaving the scope.
Some resources:
https://wiki.openjdk.java.net/display/loom/Structured+Concurrency
https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html#struc…
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statemen…
nfoz · 2020-12-04
The article seems to assume you know what Project Loom is. (Not to be confused with Google's Project Loon, the balloon thing.)
From https://wiki.openjdk.java.net/display/loom/Main, it's an OpenJDK project:
> Project Loom is to intended to explore, incubate and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform.
A bit more history/explanation here:
http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
haxen · 2020-08-05
http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html#forced…
Yes it can and actually it's quite low-hanging fruit on the JVM. GC safepoints are already there, you just have hook into the mechanism.
SureshG · 2020-06-19
Hopefully will preview in next release (6 months release cycle)
http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
EAP build - http://jdk.java.net/loom/
gavinray · 2020-06-05
I don't know anything about the JVM and my experience with JVM-based languages is incredibly limited, but isn't that the essence of the Loom Project?
https://developers.redhat.com/blog/2019/06/19/project-loom-lightweight…
https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
brabel · 2020-06-04
If you think async/await is the holy grail of networking, you're up for a surprise in the next few years.
The problem with async/await: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-functi…
A solution proposed by none other than Java (available as an experimental feature in JDK 15): http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
This seems to me to obsolete async/await, quite honestly.
apta · 2020-05-21
Loom will have superior context cancellation and deadline handling than golang. https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html
Felz · 2019-11-07
I think Project Loom would fit. It's a remarkably sane approach:
https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
akerro · 2018-10-09
There is also project Loom that will go into Java http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
kitd · 2018-10-09
Project Loom [1] is intended to provide green threads, or 'fibers', at the JVM level.
There have been other projects like Quasar from ParallelUniverse [2] that retrofits them by processing the compiled bytecode to enable saving/restoring the IP & stack.
[1] http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
[2] http://docs.paralleluniverse.co/quasar/
sgift · 2018-10-09
There is a proposal to add fibers to Java: http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
nu11ptr · 2022-05-02
From http://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1.html:
"Whereas the OS can support up to a few thousand active threads, the Java runtime can support millions of virtual threads. Every unit of concurrency in the application domain can be represented by its own thread, making programming concurrent applications easier. Forget about thread-pools, just spawn a new thread, one per task. You’ve already spawned a new virtual thread to handle an incoming HTTP request, but now, in the course of handling the request, you want to simultaneously query a database and issue outgoing requests to three other services? No problem — spawn more threads. You need to wait for something to happen without wasting precious resources? Forget about callbacks or reactive stream chaining — just block. Write straightforward, boring code. All the benefits threads give us — control flow, exception context, debugging flow, profiling organization — are preserved by virtual threads; only the runtime cost in footprint and performance is gone. There is no loss in flexibility compared to asynchronous programming because, as we’ll see, we have not ceded fine-grained control over scheduling."
This seems so obvious in hindsight as the "right way". I wonder why we went down that whole async/await craze with so many languages?