Hacker News new | ask | show | jobs
by mikko-apo 1038 days ago
Before virtual threads, Java server would reserve a full OS thread while that code is being processed. OS threads use lots of memory and there might a limited number available. With a single incoming request or low traffic that is not a problem, but with many parallel requests the server would choke on using too much memory or OS threads.

Previously in Java if you wanted to avoid code that blocks the OS thread you would need to use callback based code or reactive programming: https://www.alibabacloud.com/blog/how-java-is-used-for-async...

Javascript moved on from callbacks to async/await, which colors the async functions and requires the programmer to be aware of the issues related to async/await.

For Java Project Loom takes a different approach. For example with server applications, the server would start running the code in a virtual thread and most of the code that looks like blocking will actually work like unblocking code. You get to use regular blocking code but you get async performance.

When the code needs to wait for a response, JVM can unmount the virtual thread from the OS thread and then the JVM can run another virtual thread in the OS thread. Once the response is returned and the OS thread is free, JVM can continue executing the original request.

There are some caveats to virtual threads. There is some overhead (but not a lot), some IO calls still block (but you don't get an indication about using blocking IO) and you might stumble on new kinds of bugs related to resource exhaustion (try reserving a million OS file handles).

But no more async/await, reactive programming, callbacks. Mostly just regular imperative blocking-looking code. I'm very excited about that.

1 comments

what are the issues with async/await?
the mental gymnastics.

Having fun using async/await in loops? https://zellwk.com/blog/async-await-in-loops/

An actual blocking model is much easier to grok.

This could be solved by using for..of in an asnyc function though.

It might look like surprsising behavior maybe, but putting the async keyword outside and looping without non-awaited callbacks is the only possible way to keep the semantics sound, no?

In other words, forEach would have to return a Promise too. That's where the function coloring rightfully annoys programmers to catch their mistakes, there are if cause also lint rules for this.

AFAIK there are two active proposals that aim to provide this natively (and additonaly enable working with lazy and/or infinite iterators or generator functions):

AsyncIterator and tc39/proposal-async-iterator-helpers

Things don’t have to be that way. You can reject the use of async/await in contexts that aren’t aware of it (delegating it to special APIs that properly handle it).
Can you elaborate? Do you mean like the Promise API with the "spesialisti APIs"?
You could have a forEach that awaits the promise created each iteration, for example.
Because that's what "blocking" calls were invented to avoid.