I am trying to understand what does Locked ownable synchronizers
refer to in a thread dump?
I started using ReentrantReadWriteLock
have a thread in WAITING
state, waiting for a ReentrantReadWriteLock$FairSync
in the "locked ownable synchronizers" list of another thread in WAITING
state (a ThreadPoolExecutor
).
I couldn't find much information about that. Is it some kind of locks "passed onto" the thread? I'm trying to figure out where my deadlock comes from and I can't see any thread actively locking those (i.e. no corresponding - locked <0x...>
in any stack trace).
Correct use ReentrantLock it isn't so easy as it seems. It has several pitfalls. If we speak about deadlocks i think you need to know :
1.
It's from nice article "Java concurrency: the hidden thread deadlocks"
If you have access to source code getReadHoldCount() method can help in investigation deadlocks.
2. Correct upgrade from readLock to writeLock - "Java ReentrantReadWriteLocks - how to safely acquire write lock?"
From Java 7 documentation:
TL;DR: write locks appear in the "ownable synchronizers" list, read locks don't.
I ended up with the following MVCE to try and understand what's with "ownable synchronizer". The idea was to have two threads locking/unlocking read/write reentrant locks and see the effect on different thread dumps at different timings (taken in jVisualVM while the Eclipse project was paused in breakpoints at specific lines).
Here is the code (in package "lock"):
Here is the output:
Now, thread dumps.
Thread dump #1 is taken when thread "main" got a read lock. As we can see, no "ownable synchronizer" is owned by the thread:
Thread dump #2 is taken after thread "other" has taken the write lock. It appears in the "ownable synchronizers":
Thread dump #3 is taken after thread "other" has released the write lock (and died), and thread "main" has taken it:
So write locks will appear in the list of "locked ownable synchronizers", when read locks won't. Even though
getReadHoldCount()
shows the number of read locks taken by the current thread, a read "locking" doesn't seem to belong to a particular thread and is therefore absent from the list. And that makes it difficult to debug deadlocks (or let's say "not as easy as with jVisualVM").EDIT: To help figuring out copy/paste errors with locks taken and not released such as in:
you can use the following Linux command line at the root of your source directory:
will display how many read locks are taken, and:
will display how many read locks are released. If numbers don't match, remove the
| wc -l
to show the details of file names (grep -H
) and line number (grep -n
).