Live data from Hacker News

Java Virtual Threads: A Case Study

infoq.com

101–110 of 199 posts

Re: Java Virtual Threads: A Case Study

#101
post #98
post #91

Earlier quoted context omitted.

I don't think that this would be a good showcase for Virtual Threads. The "async" API for Java is CompletableFutures, right? thats been stable for something like 10 years, so no real change since Java 8. You'd jsut have to define a ThreadPool with n Threads before, where each request would've blocked one pending thread. Now it just keeps going. So your equivalent Java example should've been something like this, but a…

Structured concurrency is still being developed: https://openjdk.org/jeps/453 Also, I wouldnt consider that the equivalent Java code. That is all Spring and Lombok magic. Just write the code and just use java.net.HttpClient.

> and just use java.net.HttpClient.

No.

Re: Java Virtual Threads: A Case Study

#102

Earlier quoted context omitted.

> Async runtimes are always complicated, filled with leaky abstractions, it’s like another language that one has to learn in addition, but with a less thought-out, ad-hoc design. Difficult to reason and debug, especially in edge cases Async runtimes themselves are simply attempts to bolt-on green threads on top of a language that doesn't support them on a language level. In JavaScript, async/await uses Promises to en…

>Async runtimes themselves are simply attempts to bolt-on green threads on top of a language that doesn't support them on a language level. Haskell supports async code while also supporting green threads on a language level, and the async code has most of the same issues as async code in any other languages.

What problems exactly? Haskell has a few things that imo it does better than most languages in this area:

- All IO is non-blocking by default.

- FFI support for interruptible.

- Haskell threads can be preempted externally - this allows you to ensure they never leak. Vs a goroutine that can just spin forever if it doesn't explicitly yield.

- There are various stdlib abstractions for building concurrent programs in a compositional way.

Re: Java Virtual Threads: A Case Study

#103
post #71

Earlier quoted context omitted.

"they run virtual threads as needed" - so when one virtual thread is no longer needed and another one is needed, they switch context, yes?

This is called mounting/un-mounting and is much cheaper than a context switch.

This is a type of context switch. You are saying dollars are cheaper than money.

Re: Java Virtual Threads: A Case Study

#104
post #86
post #37

Earlier quoted context omitted.

> My rough understanding is that this is similar to async/await in .NET? Not really. What C# does is sort of similar but it has the disadvantages of splitting your code ecosystem into non-blocking/blocking code. This means you can “accidentally” start your non-blocking code. Something which may cause your relatively simple API to consume a ridiculous amount of resources. It also makes it much more complicated to upda…

Erlang, not Go, should be the obvious choice for concurrency, but it's impossible to retrofit Erlang's concurrency onto existing systems.

As an Erlang person, from reading about Java's Virtual Threads, it feels like it should get a significant portion of the Erlang concurrency story.

With virtual threads, it seems like if you don't hit gotchas, you can spawn a thead, and run straight through blocking code and not worry about too many threads, etc. So you could do thread per connection/user chat servers and http servers and what not.

Yes, it's still shared memory, so you can miss out on the simplifying effect of explicit communication instead of shared memory communication and how that makes it easy to work with remote and local communication partners. But you can build a mailbox system if you want (it's not going to be as nice as built in one, of course). I'm not sure if Java virtual threads can kill each other effectively, either.

Re: Java Virtual Threads: A Case Study

#105
post #72

Earlier quoted context omitted.

A thread per request has a high risk of overcommitting on CPU use, leading to a different set of problems. Virtual threads are scheduled on a fixed-size (based on number of cores) underlying (non-virtual) thread pool to avoid this problem.

Why can't virtual threads overcommit CPU use? If I have 4 CPUs and 4000 virtual threads running CPU-bound code, is that not overcommit? A system without overcommit would refuse to create the 5th thread.

I think parent is saying overcommit with OS threads. 4k requests = 4k OS threads. That would lead to the problems parent is talking about.

Re: Java Virtual Threads: A Case Study

#106

Similarly the power of golang concurrent programming is that you write non-blocking code as you write normal code. You don't have to wrap it in functions and pollute the code but moreover, not every coder on the planet knows how to handle blocking code properly and that is the main advantage. Most programming languages can do anything the other languages can do. The problem is that not all coders can make use of it.…

Can we stop pretending Erlang does not exist?

Go is a next-gen trumpian language that rejects sum types, pattern matching, non-nil pointers, and for years, generics; it's unhinged.

Re: Java Virtual Threads: A Case Study

#107
post #37

My rough understanding is that this is similar to async/await in .NET? It’s a shame this article paints a neutral (or even negative) experience with virtual threads. We rewrote a boring CRUD app that spent 99% of its time waiting the database to respond to be async/await from top-to-bottom. CPU and memory usage went way down on the web server because so many requests could be handled by far fewer threads.

> My rough understanding is that this is similar to async/await in .NET? Not really. What C# does is sort of similar but it has the disadvantages of splitting your code ecosystem into non-blocking/blocking code. This means you can “accidentally” start your non-blocking code. Something which may cause your relatively simple API to consume a ridiculous amount of resources. It also makes it much more complicated to upda…

It's foolish to say that green threads are strictly better and ignore async/await as something outdated. It can do a lot that green threads can't.

For example, you can actually share a thread with another runtime.

Cooperative threading allows for implicit critical sections that can be cumbersome in preemptive threading.

Async/await and virtual threads are solving different problems.

> What is perhaps worse is that C# lacks an interruption model

Btw, You'd just use OS threads if you really needed pre-emptively scheduled threads. Async tasks run on top of OS threads so you get both co-opertive scheduling within threads and pre-emptive scheduling of threads onto cores.

Re: Java Virtual Threads: A Case Study

#108
post #65
post #58

Earlier quoted context omitted.

It's a different model. Microsoft did work on green threads a while ago and decided against continuing. Links: https://github.com/dotnet/runtimelab/issues/2398 https://github.com/dotnet/runtimelab/blob/feature/green-thre...

It should be pointed out, that the main reason they didn't go further was because of added complexity in .NET, when async/await already exists. > Green threads introduce a completely new async programming model. The interaction between green threads and the existing async model is quite complex for .NET developers. For example, invoking async methods from green thread code requires a sync-over-async code pattern that…

It would break a lot of the native interop and UI code devx of the language. Java was never as nice in those categories so it had less to lose going this path.

Re: Java Virtual Threads: A Case Study

#109
post #23

Earlier quoted context omitted.

It's combining the benefits from async models (state machines separated from os threads, thus more optimal for I/O bound workload), with the benefits from proper threading models (namely the simpler human interface). Memory utilization & performance is going to be similar to the async callback mess.

Why is an async model better than using OS threads for an I/O bound workload? The OS is doing async stuff internally and shielding the complexity with threads. With virtual threads this work has shifted to the JVM. Can the JVM do threads better than the OS?

"Why is an async model better than using OS threads for an I/O bound workload?"

Because evented/callback-driven code is a nightmare to reason about and breaks lots of very basic tools, like the humble stack trace.

Another big thing for me is resource management - try/finally don't work across callback boundaries, but do work within a virtual thread. I recently ported a netty-based evented system to virtual threads and a very long-standing issue - resource leakage - turned into one very nice try/finally block.

Re: Java Virtual Threads: A Case Study

#110
post #51

My rough understanding is that this is similar to async/await in .NET? It’s a shame this article paints a neutral (or even negative) experience with virtual threads. We rewrote a boring CRUD app that spent 99% of its time waiting the database to respond to be async/await from top-to-bottom. CPU and memory usage went way down on the web server because so many requests could be handled by far fewer threads.

> 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 differen…

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.
Post reply on HN