Earlier quoted context omitted.
The problem with ChatGPT is that, when it should say "I don't know", it will instead confidently spew plausible sounding garbage.
So, like most people?
Java 20 / JDK 20: General Availability
311–320 of 356 posts
Re: Java 20 / JDK 20: General Availability
#312Earlier quoted context omitted.
The problem of scaling threads up further is fundamental and not really solvable by more kernel features. JVM virtual threads can be efficient because the runtime has complete knowledge of the executing code and stack layouts, how the heap is laid out, how the GC works and it can control how code is compiled. The kernel can't do any of these things - it has to assume a process is a black box that could do anything wi…
> JVM virtual threads can be efficient because the runtime has complete knowledge of the executing code and stack layouts, how the heap is laid out, how the GC works and it can control how code is compiled. Forgive me for staying doubtful, but I recall hearing this same "the JVM can be very fast and efficient because its JIT has complete knowledge and control" spiel back in the 90s, and back then, anyone could clearl…
Well head-for-head Java will still lose to C++ in many benchmarks, but that's not really due to compiled code quality, it's more about language semantics. Java is very fast for the sort of language it currently is. The big wins for C++ are that Java doesn't have value types or support for vector operations. Both are under development, actually vector ops is basically done but it's waiting for support for value types (see discussion elsewhere).
Also GCd languages trend towards a functional style without much in-place mutation, whereas C++ trends in the opposite direction, so C++ will sometimes use the CPU cache more effectively just due to prevailing habits amongst programmers.
> The kernel has to assume nothing; it can dictate how userspace processes behave.
Yes in theory you could fuse the language VM with the kernel and research operating systems like MSR Singularity did that. But a normal kernel like NT, Linux or Darwin can't do this and not only for backwards compatibility. The JVM will do things like move a virtual thread stack back and forth from the garbage collected heap and do so on the fly. Unless the kernel contains a JIT compiler, GC and injects lots of runtime code into the app's process it's going to find it tricky to do the same. By the time you've done the same you haven't implemented better kernel threads, you've made the JVM run in the kernel.
Re: Java 20 / JDK 20: General Availability
#313Earlier quoted context omitted.
> Async/await allows to write concurrent code with no synchronization Well you still need some sort of synchronization, because an "await" allows arbitrary other actions to occur. If an await is introduced in code you transitively call then you might find that some invariant you were expecting to hold has now changed across a call when it previously didn't. Fundamentally, locks are about making invariants atomic and…
This is impossible because of *gasp function coloring. You can't just make a sync function async without dealing with the fallout explicitly in c#.
Re: Java 20 / JDK 20: General Availability
#314This is exciting, can't wait for the LTS release next year... that said, I don't much care for the "case SomeType t when ..." pattern matching syntax, I don't see the benefit of introducing a new keyword over using "if"... or even just "&&". To pinch the example used in[1]: case Tuner t && guitar.isInTune() -> ...; and case Tuner t if guitar.isInTune() -> ...; both seem as clear as case Tuner t when guitar.isInTune()…
var favoriteTask = obj switch
{
Developer dev when dev.YearOfBirth == 1980 => $"{dev.FirstName} listens to metal",
Developer dev => $"{dev.FirstName} writes code",
Manager _ => "Create meetings",
_ => "Do what objects do",
};Re: Java 20 / JDK 20: General Availability
#315Earlier quoted context omitted.
There are bullshitters in the real world, but for the most part they tend to just say "I don't know" in a really convoluted way. They won't, for example, completely fabricate entire concepts and speak confidently and in detail about them. For example, I asked ChatGPT about the meaning of a non-existing verb ("to spoink"). It originally said the word didn't exist, but when I said "are you sure? we talked about it befo…
Why not? "Spoink" is a perfectly cromulent word!
Re: Java 20 / JDK 20: General Availability
#316Really excited to see how virtual threads are taken up by developers, and if they affect the larger programming language community. They just really seem like "the best of both worlds" to me: the high scalability/low resource usage of async/await, with the ease-of-use experience of threads (e.g. not having to worry about "function coloring").
The fact that they’re cooperatively scheduled makes them quite problematic. Basically a leaky abstraction, you have to think whether your code will block or not. Go went through the same process, before eventually figuring out that they do need to make their lightweight threads (goroutines) preemptive.
Re: Java 20 / JDK 20: General Availability
#317Earlier quoted context omitted.
The fact that they’re cooperatively scheduled makes them quite problematic. Basically a leaky abstraction, you have to think whether your code will block or not. Go went through the same process, before eventually figuring out that they do need to make their lightweight threads (goroutines) preemptive.
Can you expand why its a leaky abstraction? Is it because virtual threads can only yield when its doing blocking operations?
When you're in a "tight loop" (e.g. a matrix multiplication, which is basically 3 nested loops that only load data, do math, write data), Java's virtual threads just won't yield. So if you write your app in the "wrong" way, you lose concurrency.
There's a lot of discussion about this from the Go side. The original issue was this one: runtime: tight loops should be preemptible https://github.com/golang/go/issues/10958
> it's possible to write a tight loop (e.g., a numerical kernel or a spin on an atomic) with no calls or allocation that arbitrarily delays preemption. This can result in arbitrarily long pause times as the GC waits for all goroutines to stop.
The proposed (and ultimately accepted, AFAIK) solution is described here: https://github.com/golang/go/issues/24543
> has put significant effort into prototyping cooperative preemption points in loops, which is one way to solve this problem. However, even sophisticated approaches to this led to unacceptable slow-downs in tight loops (where slow-downs are generally least acceptable).
> I propose that the Go implementation switch to non-cooperative preemption using stack and register maps at (essentially) every instruction. This would allow goroutines to be preempted without explicit preemption checks. This approach will solve the problem of delayed preemption with zero run-time overhead and have side benefits for debugger function calls
I 100% expect Java will have to do through the same evolution. But first they'll probably try to deny reality for a few years. Funny enough, same as has happened with Go and generics.
Re: Java 20 / JDK 20: General Availability
#318Earlier quoted context omitted.
I'm personally not so sure. We already had something like that before (M:N threads), and the world moved away from it, towards letting the kernel manage everything (1:1 threads). So I'd expect instead that operating system kernels gain whatever features are missing for scaling to a higher number of threads, and everything once again goes back to each programming language thread corresponding to one kernel thread.
M:N is not the interesting aspect of virtual threads at all, automagically turning blocking operations into non-blocking is - which has not really been tried before (with erlang and go being the first).
I'm not very into this Loom virtual threads thing, but... what's the difference between this automagically conversion of blocking into non-blocking in a M:N model and a 1:1 one? I mean, couldn't the same be done with normal threads too?
Re: Java 20 / JDK 20: General Availability
#319Earlier quoted context omitted.
The “&&” one is bizarre, it makes it look like the whole thing is a Boolean expression, which it absolutely is not. That gets even weirder because the part right of it actually is a Boolean expression, so on top of very confusing reading you now make it look like there are strange interactions with operator precedence. Using && is one of the worst choices. The “if” one does not suffer from any such problem and reads…
I think Rust uses "if" for its match guards too and I don't recall it upsetting anyone. I'm all for keeping things consistent between languages if only to prevent too much bike shedding.
Re: Java 20 / JDK 20: General Availability
#320Earlier quoted context omitted.
Are you really actually using CORBA? That would be heartwarming if so. Maybe just RMI over IIOP?
It's far less exciting I'm afraid: we use [0] to generate our DB IDs and it implements org.omg.CORBA.portable.IDLEntity. We could fork it and remove the interface or switch to ULID[1] instead. [0] https://github.com/stephenc/eaio-uuid/blob/master/src/main/j... [1] https://github.com/ulid/spec
Given that interface is trivial, you could also just define it in your codebase. I've done that a few times for shimming small bits of log4j and Spring that some library uses, when i would rather not have those as a dependency.