I see that formerly it pinned virtual threads "when it executes code inside a synchronized block or method", and "frequent pinning for long durations can harm the scalability of an application by capturing carriers". You were supposed to "avoid frequent and long-lived pinning by revising synchronized blocks or methods that run frequently and guard potentially long I/O operations to use java.util.concurrent.locks.ReentrantLock instead."
How big a problem was this in practice? On the one hand, I think "harm the scalability" is putting it mildly—if you have a whole bunch of virtual threads doing IO, only running num_cores of them at once is devastating. On the other hand, holding a lock while doing IO smells wrong. Is this really common?