an attempt to enter a synchronized block pins the virtual thread seemingly contrary to JEP 425 description
Alan Bateman
Alan.Bateman at oracle.com
Thu Jun 23 08:26:22 UTC 2022
On 22/06/2022 23:16, Valentin Kavalenka wrote:
> MongoDB Java driver uses synchronized blocks/methods in some places.
> When reading "JEP 425: Virtual Threads", the team saw that
>
> > There is no need to replace synchronized blocks and methods that are
> used infrequently (e.g., only performed at startup) *or that guard
> in-memory operations*.
>
> Our understanding is that the part of the above sentence talking about
> blocks that guard in-memory operations implies that an attempt to
> enter a synchronized block (an attempt to lock the monitor) works
> similarly to an attempt to acquire a ReentrantLock: it allows the
> virtual thread to be unmounted and another virtual thread to be
> mounted on the same carrier if the carrier would have been blocked
> otherwise, because of the monitor being locked by another thread. This
> understanding is consistent with the list of scenarios from JEP 425
> that describe when a virtual thread is pinned (note how #1 talks
> specifically about executing code inside a synchronized method and
> does not talk about attempting to lock the monitor):
>
> > 1. When it executes code inside a synchronized block or method, or
> > 2. When it executes a native method or a foreign function.
>
> When experimenting, we noticed that it is possible to write an
> application that uses the driver and hangs as a result of carriers
> being "consumed" by virtual threads pinned to them not because those
> virtual threads execute code inside a synchronized method, but because
> they are attempting to lock a monitor in order to start executing a
> synchronized method, which is being executed by another thread. We
> also confirmed with a simple code that does not use the driver, that
> an attempt to lock a monitor is enough to pin a virtual thread. That
> is, a virtual thread is pinned to its carrier as soon as it attempts
> to enter a synchronized block, it stays pinned until the monitor is
> released by another thread, and then continues to be pinned while it
> executed the code inside the synchronized block (this last part is
> what the JEP 425 informs about).
>
> Could you please help us to understand whether this is
> - a peculiarity of the early access builds (reproduced on OpenJDK
> Runtime Environment (build 19-ea+27-2074)), and the released JDK 19
> will not behave this way;
> - an intended behavior that may be worth specifying in the JEP
> description by updating the first scenario describing when a virtual
> thread may be pinned;
> - something else?
>
This is expected behavior. A current limitation is that a virtual thread
cannot be unmounted when it is blocked on monitor enter (as the monitor
is owned by another thread). The text you quote from the JEP is correct
and I think you are just asking that it be expanded to cover this case.
I don't know anything about the MongoDB driver but it might be the
locking around the socket I/O needs addition rather than all monitors,
meaning you may not have to replace the monitors used to guard data
structures when you aren't doing I/O in the locked regions.
-Alan
More information about the loom-dev
mailing list