3 ms·
> Code that's meant to be pinned (and may behave incorrectly if not pinned) looks no different from any other code. Same goes for async/await. The decision to
by pron 6y ago
> Code that's meant to be pinned (and may behave incorrectly if not pinned) looks no different from any other code.
Same goes for async/await. The decision to keep you running on the same native thread is up to the scheduler.
> Java isn't positioned as a high-level, high-abstraction language and that's not, IME, the user community it has.
I beg to differ. It aims to be a good compromise between productivity, observability and performance. Every choice, from JIT to GC, is about improving performance for the common case while helping productivity, not improving performance by adding fine-grained control. There are a few cases where this is not possible. Primitives is one of them, and, indeed, 25 years later, we're "expanding" primitives rather than find some automatic way for optimal memory layout.
> It's always been advertised as a safer alternative to C++ - rather like Rust.
I think you're mistaken, and in any event, this is certainly not our position. Java is designed for a good blend of productivity, observability and performance, and unless the circumstances are unusual, it opts for improving common-case performance with high abstractions rather than worst-case performance with low abstractions like C++/Rust. Roughly speaking, the stance on performance is how do we get to 95% with the least amount of programmer effort.
Anyway, regardless of what I said above, the constraints on the design of usermode threads other than philosophy are also very different for Java than for C++/Rust for reasons I mentioned. Still, Zig does it more like Java (despite still using the words async and await, but they mean something more like Loom's submit and join than what they mean in C#): https://youtu.be/zeLToGnjIUM https://youtu.be/zeLToGnjIUM
- lmm 6y ago> Same goes for async/await. The decision to keep you running on the same native thread is up to the scheduler. The scheduler decides what happens at each yield point, but code that doesn't yield is guaranteed to stay pinned to a single native thread. A non-async function is somewhat analogous to a critical section; the difference between async and not is a visible distinction between must-run-on-a-pinned-native-thread functions and may-be-shuffled-between-native-threads functions.
- pron 6y agoCan you give an example where this matters -- i.e. it's useful and allowed to move between native threads but not between well-known points -- given that the identity of the carrier thread cannot leak to the virtual thread?