Hacker News new | ask | show | jobs
by he0001 695 days ago
> My rough understanding is that this is similar to async/await in .NET?

The biggest difference is that C# async/await code is rewritten by the compiler to be able to be async. This means that you see artifacts in the stack that weren’t there when you wrote the code.

There are no rewrites with virtual threads and the code is presented on the stack just as you write it.

They solve the same problem but in very different ways.

2 comments

> They solve the same problem but in very different ways.

Yes. Async/await is stackless, which leads to the “coloured functions” problem (because it can only suspend function calls one-by-one). Threads are stackful (the whole stack can be suspended at once), which avoids the issue.

There is overlap but they really don't solve the same problem. Cooperative threading has its own advantages and patterns that won't be served by virtual threads.
What patterns does async/await solve which virtual threads don’t?
If you need to be explicit about thread contexts because you're using a thread that's bound to some other runtime (say, a GL Context) or you simply want to use a single thread for synchronization like is common in UI programming with a Main/UI Thread, async/await does quite well. The async/await sugar ends up being a better devx than thread locking and implicit threading just doesn't cut it.

In Java they're working on a structured concurrency library to bridge this gap, but IMO, it'll end up looking like async/await with all its ups and downs but with less sugar.

What’s stopping you from using a single thread for synchronization?
You can use virtual threads running on a single OS thread and that will work but then everything will be on that one thread. You'll have synchronization but you'll also always be blocking on that one thread as well.

Async/await is able to achieve good UX around explicitly defining what goes on your Main thread and what goes elsewhere. Its trivial to mix UI thread and background thread code by bouncing between synchronization contexts as needed.

When the threading model is implicit its impossible to have this control.

"Green Threads" as implemented in Java is a solution that solves only a single problem - blocking/multiplexing.

It does not enable easy concurrency and task/future composition the way C#/JS/Rust do, which offer strictly better and more comprehensive model.

Structured concurrency[1] offers task composition and more.

[1] https://openjdk.org/jeps/453

What do you mean? It implements the Future/Task interface and you can definitely use that. In fact you can’t tell the difference from a virtual thread vs a platform one, and it’s available everywhere. I for one thinks it’s much easier to use than the async/await pattern as I don’t need any special syntax to use it.