News for hackers. Stuff that matters.
Re:Guide to Java Virtual Threads by jayd16 on Wednesday March 15, 2023 @08:26PM (#35176569)
It's not really an alternative to async/await. Implicit vs cooperative multithreading have pros and cons for each.
Re:Guide to Java Virtual Threads by capableweb on Wednesday March 15, 2023 @09:01PM (#35176849)
Authors of Loom seems to disagree with you.

> An alternative solution to that of fibers to concurrency's simplicity vs. performance issue is known as async/await, and has been adopted by C# and Node.js, and will likely be adopted by standard JavaScript. Continuations and fibers dominate async/await in the sense that async/await is easily implemented with continuations (in fact, it can be implemented with a weak form of delimited continuations known as stackless continuations, that don't capture an entire call-stack but only the local context of a single subroutine), but not vice-versa.

> While implementing async/await is easier than full-blown continuations and fibers, that solution falls far too short of addressing the problem. While async/await makes code simpler and gives it the appearance of normal, sequential code, like asynchronous code it still requires significant changes to existing code, explicit support in libraries, and does not interoperate well with synchronous code. In other words, it does not solve what's known as the "colored function" problem.

This is under the section called "Other Approaches" in https://cr.openjdk.org/~rpressler/loom/Loom-Proposal.html

That seems to indicate to me that async/await would be an alternative to virtual threads.

Re:Guide to Java Virtual Threads by throw868788 on Wednesday March 15, 2023 @11:09PM (#35177688)
There are differences between implicit/pre-emptive and co-operative multitasking though and there is probably tradeoffs for each. For Java however, much of the existing API exposes Threads, and locks. How do you introduce better scale of existing threading code without too much porting/changes to existing codebases wihtout significant rewrites? The "we are where we are" problem exists a lot more in Java than say .NET/Node/Go/etc which IMO tips the scales more to this kind of approach.

I think that both approaches solve a lot of the same problems, but there is some problems that fit one paradigm better than the other and I don't think they are entirely mutually exclusive either. I've heard it mentioned with Loom it solves the async "colour" probglem however I think people "overblow" the color problem of the Async API too much. If most things are async it isn't really that painful. I actually like when something is marked "async" and I have to be careful how to use it. How is it async? Can the code run in parallel and join later? Is there race condition potential? Deadlock? How is it actually async, what's it sync vs async behaviour? How do I propogate the need to halt the async operation across multiple layers? Who owns the whole workflow, can I make sure the async context is propagated to that layer so they can cancel it for example?

Probably an unpopular opinion but knowing a method has async behavior, at the type level, could be a feature not a bug. It forces you to handle it at the sync/async junction and think about these things.

Re:Guide to Java Virtual Threads by pron on Thursday March 16, 2023 @07:24AM (#35180575)
> I think people "overblow" the color problem of the Async API too much. If most things are async it isn't really that painful.

There are two problems with async/await's cooperative multitasking:

1. The is only relevant to languages that also have threads: it splits the APIs into two worlds with very similar semantics but disjoint syntactic "universes." You always need a separate API for either world, and need to do everything twice.

2. Even when that is the only paradigm, it is less composable. When scheduling points are explicit, adding a scheduling point inside a subroutine requires changing all of its callers, transitively. In contrast, with non-cooperative multitasking, any subroutine in the hierarchy can individually choose to exclude interleaving (and in a finer-grained way) for atomic operations with various constructs (the simplest being locks). Since most operations need not be atomic and are independent, this is not only more composable and evolvable, but also a more reasonable default.

Re:Guide to Java Virtual Threads by gpderetta on Thursday March 16, 2023 @07:24AM (#35180577)
Async annotations in the vast majority of languages (possibly outside of JS and maybe rust) don't protect any useful invariant. You can still block in async code by calling any already existing blocking function not marked async, and async code can run in parallel when you have multiple underlying executors and shared memory.

If you design a language form scratch, async could be useful, but even then there would no need to annotate functions as they could be inferred. Generally effect systems seem a superior solution anyway.

Re:Guide to Java Virtual Threads by esprehn on Thursday March 16, 2023 @01:13AM (#35178351)
That statement also contains factual errors. async/await came from standard JS (as part of the harmony track of work) not from node.
Re:Guide to Java Virtual Threads by whizzter on Thursday March 16, 2023 @04:50AM (#35179639)
Yes, but I would hold that the impetus for pushing it through was from what people in the Node community was doing.

Once the early code Node became actually used the callback pyramids of doom started gaining notoriety, there was even a small period before async/await where people abused generators achieve a similar style of code(The name of the Koa framework was a play on generator co-routines) ,luckily everyone migrated over afterwards.

Re:Guide to Java Virtual Threads by jayd16 on Thursday March 16, 2023 @10:28AM (#35182430)
There's some overlap for sure, but if you're trying to juggle tasks on a UI thread with fine grain control, Loom code is going to look like await without the sugar.

Hopefully I'm wrong and there's a new golden age of GUI programming in Java but I'm currently sceptical.

Re:Guide to Java Virtual Threads by gpderetta on Thursday March 16, 2023 @07:19AM (#35180537)
async/await vs virtual threads is about stackfull vs stackless. Coperative vs preemptive multitasking is completely orthogonal.
Re:Guide to Java Virtual Threads by jayd16 on Thursday March 16, 2023 @10:23AM (#35182368)
Can you explain how it's orthogonal when async/await is cooperative and virtual threads are pre-emptive?
Re:Guide to Java Virtual Threads by gpderetta on Thursday March 16, 2023 @11:09AM (#35182950)
Async is cooperative only if your executor is single threaded. If you have multiple events loop running in parallel (for example multiple c++ coroutines running in an ASIO io_service pool), it is indistinguishable from a preemptive model.

Of course some specific implementations can be single threaded only (js) or use shared nothing threads (rust), but that orthogonal with the model

Re:Guide to Java Virtual Threads by jayd16 on Thursday March 16, 2023 @02:53PM (#35186563)
Well I'm specifically talking about the single threaded executor case. (A very common case in UI programming).

If you call a plain function from an async function, you know it will not run on a different thread no matter the executor. In this Loom model, you don't know that.

You control the thread until you yield execution no matter the executor. Explicit async methods also means you get explicit sync methods. In that sense, you will not be pre-empted when code changes under you. You can write async tasks that you know will run atomically without locks because you never yielded execution.

In this implicit model, I don't believe that's the case. Because yield points can be added at any time and thus you can be pre-empted at any time, you need to use locks for atomicity (or give up and revert to using a normal Thread). I don't think its possible to interweave this implicit yielding with atomic execution in a way that's as simple as calling a sync function. Is there some other way?

Re:Guide to Java Virtual Threads by gpderetta on Thursday March 16, 2023 @03:00PM (#35186677)
Well we are discussing models in general.

If you do not want preemption disable it. For example in posix threads use sched_fifo and pin to one core.

Loom might provide similar features if needed.