Live data from Hacker News

We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

blog.ydb.tech

31–40 of 253 posts

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#32

Java virtual threads did not cause a deadlock here. The deadlock was a usage error. A better title would be: Naively switching to Java virtual threads caused a deadlock in TPC-C for Progress SQL.

What was the user error? Was there something obvious they did or didn't do or is it a "you're holding it wrong" kind of issue?

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#34

Earlier quoted context omitted.

Article won’t load for me. My understanding was that the switch to virtual was supposed to be relatively simple, allowing the programmer to be naive. But a user deadlock is a user deadlock, no matter the threading impl.

The issue here is currently virtual threads don't work well with the 'sychronized' keyword. Right now synchronized will pin the carrier thread. The fix was to switch to a higher-level abstraction that works with virtual threads. My understanding is there is work to make synchronized not pin the carrier thread, but that's some pretty complex and important code to change.

From a relatively brief skim and past Go and Java experience: synchronized blocks the current normal thread, so that doesn't really seem any different to me. If you starve your threads, you starve your threads.

It definitely leaves room to optimize by not pinning that thread, which would be great, but that shouldn't change semantics at all. Or is there something actually screwed up in the implementation of virtual threads that makes this a much bigger issue?

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#35

Erlang is based on virtual threads (confusingly called processes). The Erlang virtual machine schedules them on OS threads. Erlang processes communicate using message passing, preventing deadlocks. You can use millions of Erlang processes without problems, e.g., to handle millions of Elixir LiveView sessions.

Erlang has the advantage that it was built around processes and is effectively preemptive. Processes can be descheduled anytime they make a function call or use receive to get or wait for messages and being a functional language, you have a finite amount of instructions before calling a function.

Other languages adding virtual threads later in life don't have the same ability to feel preemptive. Although I think someone said Java has a nice trick or two?

Anyway, if all the virtual threads seem preemptive, you won't have the case that your limited number of actual threads are waiting on locks and not yielding --- all Erlang processes yield eventually; usually in a fairly short time frame.

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#37

[flagged]

I agree on an emotional level, but now I’m starting to wonder exactly why. Something similar from an illustrator would not be provoking to me.

Still working it out, but here’s a theory: when I’m sifting through stuff I’m looking for things that people spent time on. I have a pretty decent radar for effort, and effort is a good proxy for interesting. Even if I find it wrong or insightless, I still respect that people spend the time to express themselves.

However, these AI images are tricking my effort-heuristic and I’m annoyed that my attention has been temporarily hijacked someone spent 2 seconds on. This isn’t a new phenomenon, I’ve always been like this when I stumble across eg ads and low effort content marketing.

I think this cringe/cheesy feeling might be more a reaction to how it was made than the content itself.

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#38

Erlang is based on virtual threads (confusingly called processes). The Erlang virtual machine schedules them on OS threads. Erlang processes communicate using message passing, preventing deadlocks. You can use millions of Erlang processes without problems, e.g., to handle millions of Elixir LiveView sessions.

You can have deadlock in Erlang, it's just a bit harder. It happens when two processes are both waiting on the other to send them a message which is analogous to two threads each waiting for a mutex the other holds. The same thing can happen in Go with its channels, another message passing based concurrency control mechanism.

Sure, you can make deadlocks in any language, but it's uncommon in Erlang. Shared state is the exception, and message passing means that things that manage state, such as gen_servers, only process one message at a time from their inbox.

Contrast this with languages like Java where every object is a potential concurrency problem. Or the 10+ years of trying to make Python async (see Twisted).

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#39

This is a common problem when migrating a system from threads to virtual threads. In general, using primitives which block the current thread and prevent forward progress can quickly lead to deadlocks. It’s a hard issue to catch because in the past usually this would get “solved” by spawning a new thread to complete the task but in a world with virtual threads the runtime is usually reluctant to spawn more threads, s…

Is that all that's happening here? There's an implicit limit on real threads, where before it was unlimited by virtue of not using the virtual thread's limited pool?

If it doesn't spawn threads when all of them are blocked, that seems kinda dumb. And a severe change in semantics. It can be conservative and try running unpinned ones on fewer threads and shuffle them around and slowly spawn more to ensure eventual progress, which would mean a possibly significant optimization problem, but a hard cap impacts correctness.

Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres

#40
post #14

Concurrency, parallelism. These are among the most misunderstood concepts in programming/software development. TLS (especially mutual TLS) and Oauth also join this club.

Interestingly enough, I love both mutual-TLS and OAUTH (especially OIDC).
Post reply on HN