RFR: In rare cases, the unlock() on join() might fail, causing an IllegalMonitorStateException

Alex Otenko oleksandr.otenko at gmail.com
Thu Feb 25 20:14:52 UTC 2021


I wonder what reasons may be to want to transition from synchronized/wait
to Condition/await

Alex

On Thu, 25 Feb 2021, 14:32 Dr Heinz M. Kabutz, <heinz at javaspecialists.eu>
wrote:

> On 2021/02/25 14:07, Alan Bateman wrote:
> > On Thu, 25 Feb 2021 11:10:41 GMT, kabutz <github.com+
> 332398+kabutz at openjdk.org> wrote:
> >
> >> Unlike synchronized/wait, the Condition.await() method does not
> necessarily reacquire the lock on exit, for example if the thread is
> stopped or if CTRL+C is caused in jshell. In that case we would enter the
> finally block without the lock held and unlocking would cause an
> IllegalMonitorStateException.
> >>
> >> For example, run the following code from jshell and then press CTRL+C:
> >>
> >> Object monitor = new Object();
> >> for (int i = 0; i < 10_000; i++) {
> >>    Thread.startVirtualThread(() -> {
> >>      synchronized (monitor) {
> >>        try {
> >>          monitor.wait();
> >>        } catch (InterruptedException ignore) {}
> >>      }
> >>    });
> >> }
> >> Thread.startVirtualThread(() -> System.out.println("done")).join();
> >>
> >> Output is:
> >>
> >> |  Exception java.lang.IllegalMonitorStateException
> >> |        at ReentrantLock$Sync.tryRelease (ReentrantLock.java:175)
> >> |        at AbstractQueuedSynchronizer.release
> (AbstractQueuedSynchronizer.java:1007)
> >> |        at ReentrantLock.unlock (ReentrantLock.java:494)
> >> |        at VirtualThread.joinNanos (VirtualThread.java:635)
> >> |        at Thread.join (Thread.java:2281)
> >> |        at Thread.join (Thread.java:2366)
> >> |        at (#3:1)
> > I'm in two minds about point fixes to improve robustness with
> Thread.stop. In this case, there are other usages of Condition::await,
> including some of the blocking queue implementations in j.u.concurrent,
> that probably have the same issue.
> >
> > We want Thread::stop to go away. We terminally deprecated and degraded
> stop(Throwable) in Java 9 and finally removed the method in a later
> release, the no-arg Thread::stop needs to go the same way. The first steps
> for this are in the loom repo in the form of terminal deprecation, not
> supported for virtual threads, and ThreadGroup::stop degraded to
> unconditionally throw UOE. We've been hesitant to be move faster as there
> may be usages in the wild where it is used instead of interrupt as a
> cancellation mechanism.
> >
> > I should also say that debugger support (JDI/JDWP,JVMTI) has the
> equivalent of stop(Throwable) for "managed" usages of async exceptions.
> jshell uses a signal interrupt and JDI and maybe it's calling Thread.stop,
> I need to check that as I can't otherwise explain why you see an issue with
> ctrl-C in jshell.
> Indeed, it is not always trivial changing from synchronized/wait to
> Condition/await because of these subtle differences.
> > -------------
> >
> > PR: https://git.openjdk.java.net/loom/pull/32
>


More information about the loom-dev mailing list