Why dining philosophers from the image have more than two hands?
We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
231–240 of 253 posts
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#232Earlier quoted context omitted.
That sort of what happens, there is just a configurable hard limit on how much new thread may be created that was hit by this benchmark. As mentioned in another comment: jdk.virtualThreadScheduler.maxPoolSize
Is there no limit (ignoring outside limits, e.g. from the OS) for normal threads? I know people usually use limited size thread pools for a variety of reasons, but I can't say that I've actually tried to exceed limits in a Java process yet... That would indeed be a problem if it's not similarly unlimited by default. Configurable makes perfect sense, as does attempting to be conservative, but small hard-capped default…
>The maximum number of platform threads available to the scheduler. It defaults to 256.
Yeah, that's pretty small. >256 simultaneous synchronized calls doesn't seem particularly extreme, given how common its use is.
Tho now I wonder if you can just set this to max-int and resume like normal, or if giant values do awful things internally...
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#233Earlier quoted context omitted.
> Combine that with the fact that they chose to implement the scheduler in Java instead of C(++) and you're set for performance problems. Ah yes, the argument from the 1990s. It would make sense to understand where the JVM and its compiler are these days before making incorrect statements about performance. From your link: > Blocking network TCP IO needs a sychronized block to work This is utterly false.
So how do you implement a TCP socket? I have always had to do synchronized(something) { socketInputStream.read(); } And the dude himself says that reading from a socket is a problem if you listen to the interview.
Synchronized in this context is pretty nonsensical.
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#234public void syncMethod() {
synchronized(lock) {
// some code
}
}they could translate to
public void syncMethod() {
await reentrantLockAsync.lockAsync();
try {
await somecodeAsync();
} finally {
await lock.unlockAsync()
}
}Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#235Earlier quoted context omitted.
The change in semantics is that while in principle your OS thread will always have a turn at making progress (assuming no super heavy spin locks etc), that isn't true for virtual threads. The classic situation and the one they hit in the article is something like this, You've got some virtual threads that encounter this code, synchronized(foo) { foo.wait() } And some other virtual threads that are in charge of awakin…
The only way I can see this being a problem is if the virtual threads can't be stolen from their (now pinned) carrier thread. Because otherwise that's all true of real threads too, blocking them is the whole point of Object.wait. If there's no work-stealing from pinned carriers (or they're low-finite and normal threads are effectively infinite): yes that'd be a HUGE issue. I would be shocked if they released anything…
So yeah I can see that starving rather quickly, particularly with benchmarking-like workloads. Synchronized is very very common, 256 concurrent calls really doesn't seem all that abnormal.
If that were raised to like max-int32 would things be fine, semantically? That'd mimic real threads limits (no jvm limit at all afaict).
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#236Earlier quoted context omitted.
> The designers of Project Loom would say the exact opposite. Sure, but then again the designers of circa 2000-2010 J2EE also thought the verbosity and over-engineering was a good idea.
There might be some justification for comparing any one particular thing to the worst possible particular thing if those things have something in common. The only feature the two things you picked have in common is the word 'java'.
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#237Earlier quoted context omitted.
There might be some justification for comparing any one particular thing to the worst possible particular thing if those things have something in common. The only feature the two things you picked have in common is the word 'java'.
Also have in common the "appeal to authority": (the designers) as arbiters of good judgement
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#238Earlier quoted context omitted.
Is there a similarly low-level synchronization mechanism that doesn't work this way? .NET's does the same thing. I guess I might have preferred if both Java and .NET had chosen to use a dedicated mutex object instead of hanging the whole thing off of just any old instance of Object. But that would have its own downsides, and the designers might have good reason to decide that they were worse. Not being able to just r…
In .net async won where lock and mutex does not work (lock is like synchronized, not exactly the same, tough). That’s why most libraries use SemaphoreSlim which would work with green threads. But that’s more because of the ecosystem. I’ve barley stumble upon lock’s and mutex is mostly used in the main method since it acquires a real os mutex, not really a cheap thing but for GUIs it’s clever to check if the app is ru…
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#239Earlier quoted context omitted.
The change in semantics is that while in principle your OS thread will always have a turn at making progress (assuming no super heavy spin locks etc), that isn't true for virtual threads. The classic situation and the one they hit in the article is something like this, You've got some virtual threads that encounter this code, synchronized(foo) { foo.wait() } And some other virtual threads that are in charge of awakin…
The only way I can see this being a problem is if the virtual threads can't be stolen from their (now pinned) carrier thread. Because otherwise that's all true of real threads too, blocking them is the whole point of Object.wait. If there's no work-stealing from pinned carriers (or they're low-finite and normal threads are effectively infinite): yes that'd be a HUGE issue. I would be shocked if they released anything…
Correct you can't steal the carrier thread from an Object.wait() waiting virtual thread. This is apparently in the pipeline but it is a pretty major limitation.
Most cases of synchronized/notify/wait should probably use concurrent collections instead (as message queues) so in greenfield code it's not that big of a deal. Virtual threads make writing consumers/producers using collections way easier too.
Sadly, most Java projects are not greenfield projects.
Re: We switched to Java 21 virtual threads and got a deadlock in TPC-C for Postgres
#240Earlier quoted context omitted.
Servicing 20,000 concurrent requests on a single box where somehow threads are the bottleneck, is that not a problem that approximately no one has?
Most application webservers (by default) handle one request per thread. For mostly IO bound stuff (which many projects are), it makes sense to me that threads become a bottleneck in relatively ordinary scenarios.