News for hackers. Stuff that matters.
Re:Guide to Java Virtual Threads by vijucat on Wednesday March 15, 2023 @06:25PM (#35175566)
C# .NET had async and await in 2012, for comparison. I've always loved Java but Microsoft deserves immense credit for raising the bar, and so quickly, too.
Re:Guide to Java Virtual Threads by VagueMag on Wednesday March 15, 2023 @06:47PM (#35175769)
At least from the Java language advocates' perspective, async/await is a worse solution to the problem of async than the structured concurrency approach that virtual threads will enable.
Re:Guide to Java Virtual Threads by andrekandre on Wednesday March 15, 2023 @07:50PM (#35176300)
thats interesting, any good examples?
Re:Guide to Java Virtual Threads by VagueMag on Wednesday March 15, 2023 @08:05PM (#35176407)
Tons of writing and debate on this subject but the canonical starting point is "What Color Is Your Function?" https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
Re:Guide to Java Virtual Threads by cyberax on Wednesday March 15, 2023 @11:42PM (#35177884)
Async/await are also much slower than properly implemented (see: Golang) fibers.

Basically, with async/await you need to allocate on the heap frames for each level of the async/await call stack. You basically get a linked list of stack frames.

This is essentially isomorphic to segmented stacks that Go ditched in favor of resizable stacks, because segmented stacks kill performance if a tight loop just happens to cross a segment boundary.

Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @05:49AM (#35179961)
>Async/await are also much slower than properly implemented (see: Golang) fibers.

Are there any benchmarks to back that affirmation?

Re:Guide to Java Virtual Threads by cyberax on Thursday March 16, 2023 @07:22AM (#35180551)
Hm. I know this from my personal work, replacing Go code with an async/await code.

There's a bunch of benchmarks that compare C# async/await and Goroutines (e.g. https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-... ). Go still wins there, but they all miss the very important case of nested async/awaits.

These microbenchmarks also focus on looking at Go channels versus other synchronization methods, which in my experience is not that relevant (Go channels just suck).

I guess I'll need to write a blog post.

Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @03:00PM (#35186685)
Those benchmarks are really old, things can change quite fast when it comes to programming language implementations.
Re:Guide to Java Virtual Threads by cyberax on Thursday March 16, 2023 @08:20PM (#35190920)
I wrote a quick-and-dirty benchmark: https://blog.alex.net/benchmarking-go-and-c-async-await

Results: Go - 32ms, C# - 494ms. The difference also becomes bigger as you add more recursion levels.

Re:Guide to Java Virtual Threads by dgb23 on Thursday March 16, 2023 @02:58AM (#35178999)
Async/await proliferates. If you call await, your function must be async too.

Green threads are decoupled from synchronization.

Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @05:49AM (#35179954)
You can use tasks without async/await.
Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @05:46AM (#35179944)
async/wait is using tasks which are the equivalent of virtual threads.

What I do like to see in C# is something akin to goroutines from Go or actors in Elixir.

Re:Guide to Java Virtual Threads by shellac on Thursday March 16, 2023 @07:43AM (#35180703)
This response confuses me since goroutines and Erlang processes are really very similar to project Loom's virtual threads.

The mistake is that async/await is not equivalent to virtual threads: the former can do only a subset of what the latter can.

Re:Guide to Java Virtual Threads by guiriduro on Thursday March 16, 2023 @07:45AM (#35180712)
Virtual actors for C# are offered by solutions like MS Orleans as I understand it.
Re:Guide to Java Virtual Threads by masklinn on Thursday March 16, 2023 @08:44AM (#35181120)
> What I do like to see in C# is something akin to goroutines from Go or actors in Elixir.

A task is equivalent to a goroutine.

Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @02:25PM (#35186133)
Re:Guide to Java Virtual Threads by dopidopHN on Wednesday March 15, 2023 @06:53PM (#35175822)
My understanding is that green threads are different on the implementation side as well. Basically they are cheaper at the system level? The API do not even change much last time I checked. It’s all happening in how the JVM span threads
Re:Guide to Java Virtual Threads by seabrookmx on Wednesday March 15, 2023 @07:08PM (#35175925)
That head start has had a huge impact on the ecosystem too. Random libraries (ex: Google.Cloud.PubSub.V1) have first class, mature support for async and streams. Compare that to Python (and I'd have to assume Python is much more popular on Google Cloud) which only recently got async support and it's still kludgy. This really applies across the board for anything web related.

JavaScript/TypeScript is probably the only ecosystem with comparable async support, unless you count golang which achieves a similar result with different ergonomics. I'm still on the fence on which I personally prefer.. I can see the appeal of not having the async logic pollute the callstack, but at the same time the magic[1] way golang handles i/o seems antithetical to its philosophy of being simple and explicit (for example, with respect to error handling).

[1]: https://www.reddit.com/r/golang/comments/xiu4zg/comment/ip77...

Re:Guide to Java Virtual Threads by capableweb on Wednesday March 15, 2023 @07:44PM (#35176250)
Java Virtual Threads seems to be a ("better" in their mind) alternative than async/await, so not sure Microsoft should be credited for Java Virtual Threads?

> Also, the async/await approach, such as Kotlin coroutines, has its own problems. Even though it aims to model the one task per thread approach, it can’t rely on any native JVM construct. For example, Kotlin coroutines based the whole story on suspending functions, i.e., functions that can suspend a coroutine. However, the suspension is wholly based upon non-blocking IO, which we can achieve using libraries based on Netty, but not every task can be expressed in terms of non-blocking IO. Ultimately, we must divide our program into two parts: one based on non-blocking IO (suspending functions) and one that does not. This is a challenging task; it takes work to do it correctly. Moreover, we lose again the simplicity we want in our programs.

> The above are reasons why the JVM community is looking for a better way to write concurrent programs. Project Loom is one of the attempts to solve the problem. So, let’s introduce the first brick of the project: virtual threads.

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.

Re:Guide to Java Virtual Threads by thatnerdyguy on Wednesday March 15, 2023 @07:54PM (#35176328)
And they are experimenting with green threads now. Would be... hilarious? If it landed in .NET before Java.

https://github.com/dotnet/runtimelab/tree/feature/green-thre...

Re:Guide to Java Virtual Threads by geodel on Wednesday March 15, 2023 @10:25PM (#35177414)
In Java it is landed already as preview feature last September and will be final feature this September.
Re:Guide to Java Virtual Threads by pkulak on Wednesday March 15, 2023 @09:45PM (#35177140)
This is way better than async/await. This is Go/Erlang levels of green thread ease of use.
Re:Guide to Java Virtual Threads by metaltyphoon on Wednesday March 15, 2023 @11:02PM (#35177629)
I guess everyone is entitled to their opinion.
Re:Guide to Java Virtual Threads by riku_iki on Wednesday March 15, 2023 @10:25PM (#35177415)
> .NET had async and await in 2012, for comparison.

java had ExecutorService and futures support for a while, it is just another synthetic sugar around the same solution, although Java's approach is much more powerful and flexible.

Re:Guide to Java Virtual Threads by kitd on Thursday March 16, 2023 @03:29AM (#35179184)
Java had green threads in v1.0.
Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @05:44AM (#35179925)
Not only async, but C# had LINQ, lambdas, records, pattern matching, pointers, hardware instructions via intrinsics, stackalloc etc. before similar constructs came into Java, if they ever did.

Probably there are examples where Java introduced something first, but I don't know because I'm not so well versed in Java.

While similar and inspired by Java, I do prefer C# because is less verbose, requires less boiler plate, it generally has only one proper way to do things and is kind of jack of all trades, in the sense you can tackle any area of programming besides very low level systems programming - and It quite can reach that point, too if there will be a way to disable GC and allow manual memory management.

Web backend - check, web frontend - check, mobile apps - check, desktop - check, multi platform - check, embedded - check, games - check, VM - check, native AOT - check.

It also looks great in benchmarks: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

I am biased but since I recognize it, maybe you shouldn't downvote me just for that. :)

And what's even better than C# is F#, but that's too bad nobody likes functional programming or hire programmers to use functional languages.

Re:Guide to Java Virtual Threads by krzyk on Thursday March 16, 2023 @06:53AM (#35180322)
> Not only async, but C# had LINQ, lambdas, records, pattern matching, pointers, hardware instructions via intrinsics, stackalloc etc. before similar constructs came into Java, if they ever did.

Just a clarification regarding one statement which I know for sure is not true: Java team started working on records before C# started similar work.

I don't know about the rest.

Re:Guide to Java Virtual Threads by shellac on Thursday March 16, 2023 @07:29AM (#35180619)
And pattern matching was started in java first (goes hand-in-hand with records to some extent).
Re:Guide to Java Virtual Threads by pron on Thursday March 16, 2023 @07:17AM (#35180525)
There's plenty of stuff Java did first (or only) -- an optimising JIT, two new generations of GC (G1, ZGC--a low latency GC with <1ms max pause time), low-overhead deep profiling (Java Flight Recorder) -- but they're all in the runtime. Java's strategy since the beginning has always been to innovate on the platform and be a last-mover on the language, keeping it conservative. .NET seems to follow an opposite strategy.

That's how we've been able to avoid properties and just have algebraic data types, avoid async/await and do virtual threads, avoid string interpolation and just have safe string templates. This also allows us to keep the number of features in the language relatively low -- as we, and most of our users, like it.

Re:Guide to Java Virtual Threads by DeathArrow on Thursday March 16, 2023 @07:38AM (#35180672)
I'm sure Java dis some things first, as I said. It's great that you mention some.

>That's how we've been able to avoid properties and just have algebraic data types By algebraic data types you mean product types or sum types?

Re:Guide to Java Virtual Threads by wathef on Thursday March 16, 2023 @08:47AM (#35181162)
Both of those (sum and products) are ADTs.
Re:Guide to Java Virtual Threads by pron on Thursday March 16, 2023 @09:22AM (#35181584)
Both. Java has records for products, sealed hierarchies for sums, and offers pattern matching over them. See https://www.infoq.com/articles/data-oriented-programming-jav...
Re:Guide to Java Virtual Threads by DeathArrow on Friday March 17, 2023 @05:44AM (#35194998)
>sealed hierarchies for sums

I wouldn't call that a good example of sum types. You can use sealed classes or other mechanism in C# to emulate sum types. I was thinking about something built in the language.

Example:

type IntOrBool = | I of int | B of bool

Re:Guide to Java Virtual Threads by pron on Friday March 17, 2023 @07:03AM (#35195433)
It's built into the language and the VM (the VM enforces the "sealedness", and pattern matching uses it for exhaustiveness checks). It's just that all types in Java are nominal.
Re:Guide to Java Virtual Threads by xmcqdpt2 on Thursday March 16, 2023 @07:24AM (#35180571)
> And what's even better than C# is F#, but that's too bad nobody likes functional programming or hire programmers to use functional languages.

In JVM land there is Scala and people do hire for it, more so than any other typed FP language, AFAIK.

Re:Guide to Java Virtual Threads by vips7L on Thursday March 16, 2023 @07:24AM (#35180578)
Have you looked at the source of some of the C# benchmarks? I don’t believe they’re representative of how one would actually write C#. They’re all extremely hand tuned using raw pointers and unsafe blocks. The regex benchmark actually just delegates to a C library over FFI.
Re:Guide to Java Virtual Threads by vijucat on Saturday March 18, 2023 @11:10AM (#35209702)
Yes! It was distrust towards Microsoft that kept .NET from growing to be a universal language and kept Java in the game, to be honest. The language / framework, per se, is to be celebrated as a great leap forward borne out of the good kind of competition.