I find Java's features to be very well balanced, and only make it into the language after they've been vetted and tested in the wild by other languages.
e.g. see their take on concurrency by means of project Loom. No need for async/await and providing separate APIs for sync vs async operations. It has records and sealed types and pattern matching, and is getting destructuring soon.
For VM languages no problem, all those languages will support threads or using threads.
For non-VM interopt it will block the carrier thread if a native call causes any sort of blocking.
In Java, external to the VM calls are almost non-existent so it's not much of an issue. Likely you'd do those sorts of calls as regular kernel threads instead of the Loom virtual threads.
To clarify, by interop here I don't just mean calling foreign functions. I mean calling async foreign functions. When async is explicit, it's easy to handle it on ABI level - it's just a bunch of callbacks (or abstractions wrapping them, like tasks/futures).
For example, suppose you're writing a Windows desktop app, and you decide to do so in Java. Modern Windows APIs are async. How would you asynchronously invoke such an API? In C#, you'd just use await.
Definitely not as easy but Go managed to get it to work fairly well with some extra overhead. I would rather the language design for pure Java first and C interop second.
This approach results in more closed ecosystems, though, where everything has to be re-implemented to work well, instead of reusing existing libraries (that have been polished for decades in some cases).
Also, what about OS APIs? Those always going to be at the bottom of the stack, and they are increasingly async themselves.