Reputation: 60213
The JVM tells me that a deadlock has occurred:
Found one Java-level deadlock:
=============================
"TP-Processor107":
waiting for ownable synchronizer 0x00002aaaf58e70f0, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync),
which is held by "indexTrackerThread3"
"indexTrackerThread3":
waiting for ownable synchronizer 0x00002aaaf4394580, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync),
which is held by "TP-Processor16"
"TP-Processor16":
waiting for ownable synchronizer 0x00002aaaf58e70f0, (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync),
which is held by "indexTrackerThread3"
We can see that indexTrackerThread3
is waiting for a resource held by TP-Processor16
, and vice-versa. That is indeed a deadlock.
We can see that indexTrackerThread3
is waiting for 0x00002aaaf4394580
:
"indexTrackerThread3":
- parking to wait for <0x00002aaaf4394580>
My question:
In the threads dump, why is there no line - locked <0x00002aaaf4394580>
?
It seems like 0x00002aaaf58e70f0 is actually not locked by any thread. What could be locking it?
In all the deadlock documentation I have read (example), for every different - parking to wait for <0x123>
line, there is always one - locked <0x123>
line. So I begin suspecting a JVM bug. Am I misunderstanding something?
Note: Sorry for linking to pastebin, but the question is not answerable without having the full dump. For brevity, I removed all lines that contained " at", they do not include any lock information.
Upvotes: 6
Views: 3682
Reputation: 967
The stack trace shows that 0x00002aaaf4394580 is not locked by any thread. This can occur due to Java bug #6822370. This observation should add closure to the voted answer.
Upvotes: 0
Reputation: 385
The complexity of the Thread Dump analysis for such type of deadlock is mainly due to the usage of the java.util.concurrent package. This was built to move away from the classic and intrusive way of synchronizing Java objects. This package is very useful when for example you want to restrict the WRITE operations to a single Thread model while allowing concurrent READ operations. This approach is great from a performance tuning perspective, the side effect is an increased level of complexity of the Thread Dump analysis process when dealing with concurrency problems.
I suggest that you also review the following article. It describes problems such as hidden Java deadlock scenarios where the JVM will not even be able to detect the deadlock (due to READ locks which are normally not designed to have a notion of ownership). Sample Java program is provided as an example.
Upvotes: 0
Reputation: 1070
Different things can deadlock java threads, monitors, aka the synchronized keyword, are just one thing.
You can also dig in the definitions of ThreadMXBean.findDeadlockedThreads and ThreadMXBean.findMonitorDeadlockedThreads for more information.
As far as I am concerned, it is the monitor locking and the java 5 locking.
In thread dumps, the waiting to lock <0x123>
and locked <0x123>
combination is only for monitor locking.
With java 5 locking you get only the first part.
Something like parking to wait for <0x456>
. You then search for some 0x456 in the thread dump, but it is nowhere to be found. This is confusing.
Upvotes: 0
Reputation: 48015
Marko Topolnik's answer is correct.
As for a solution to your problem, JProfiler would show you a complete graph of threads and monitors for locking situations that involve locks from the java.util.concurrent package.
Disclaimer: My company develops JProfiler
Upvotes: 0
Reputation: 200168
The java.util.concurrent package utilizes an extralingual, native parking mechanism (as well as other native mechanisms, such as an atomic compare-and-swap). You can see what I'm talking about here.
The pattern you describe as usually occuring in the thread dump stems from the classic Java idiom synchronized(lock) { lock.wait(); }
.
Upvotes: 5