If by coroutines the author meant virtual threads, then monitors have always been compatible with virtual threads (which have always needed to adhere to the Thread specification). Monitors could, for a short while, degrade the scalability of virtual threads (and in some situations even lead to deadlocks), but that has since been resolved in JDK 24 (https://openjdk.org/jeps/491).
I think it's coroutines as in other JVM languages like Kotlin, where yielding may be implemented internally as return (due to lack of native coroutine support in JVM).
Holding a lock/monitor across a yield is a bad idea for other reasons, so it shouldn't be a big deal in practice.
I meant polyfilled coroutines used by other JVM languages, like Kotlin. When you compile a coroutine to a state machine, yielding has to return from the machine; but JVM does not support unbalanced monitors, although it obviously does support unbalanced locking operations with normal mutexes.
Comments
Nice post!
A minor point:
If by coroutines the author meant virtual threads, then monitors have always been compatible with virtual threads (which have always needed to adhere to the Thread specification). Monitors could, for a short while, degrade the scalability of virtual threads (and in some situations even lead to deadlocks), but that has since been resolved in JDK 24 (https://openjdk.org/jeps/491).
I think it's coroutines as in other JVM languages like Kotlin, where yielding may be implemented internally as return (due to lack of native coroutine support in JVM).
Holding a lock/monitor across a yield is a bad idea for other reasons, so it shouldn't be a big deal in practice.
I meant polyfilled coroutines used by other JVM languages, like Kotlin. When you compile a coroutine to a state machine, yielding has to return from the machine; but JVM does not support unbalanced monitors, although it obviously does support unbalanced locking operations with normal mutexes.