In a Java thread dump, you can see locks mentioned within stack traces.
There seems to be three kinds of information:
1:
- locked <0x00002aab329f7fa0> (a java.io.BufferedInputStream)
2:
- waiting to lock <0x00002aaaf4ff6fa0> (a org.alfresco.repo.lock.LockServiceImpl)
3:
- parking to wait for <0x00002aaafbf70bb8> (a java.util.concurrent.SynchronousQueue$TransferStack)
Runnable: Means a thread is currently executing. Blocked: The thread is waiting for a lock to be released. This happens when entering a synchronized block, for instance. Waiting / Timed_waiting: The thread is waiting for something to happen. These are joins/gets on CompletableFutures, calling Thread.
For a thread to work on an object, it must have control over the lock associated with it, it must “hold” the lock. Only one thread can hold a lock at a time. If a thread tries to take a lock that is already held by another thread, then it must wait until the lock is released.
An ownable synchronizer is a synchronizer that may be exclusively owned by a thread and uses AbstractOwnableSynchronizer (or its subclass) to implement its synchronization property. ReentrantLock and ReentrantReadWriteLock are two examples of ownable synchronizers provided by the platform.
You will get "waiting to lock" in the thread dump when using intrinsic locks and "parking to wait for" when using locks from java.util.concurrent. Consider the following example:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockTest { final Lock lock = new ReentrantLock(true); synchronized void intrinsicLock() { Thread th = new Thread(new Runnable() { public void run() { intrinsicLock(); } }, "My thread"); th.start(); try { th.join(); } catch (InterruptedException e) { } } void reentrantLock() { lock.lock(); Thread th = new Thread(new Runnable() { public void run() { reentrantLock(); } }, "My thread"); th.start(); try { th.join(); } catch (InterruptedException e) { } lock.unlock(); } public static void main(String[] args) { LockTest lockTest = new LockTest(); lockTest.intrinsicLock(); //lockTest.reentrantLock(); } }
With lockTest.intrinsicLock()
you will get the following thread dump:
"My thread" prio=10 tid=0x00007fffec015800 nid=0x1775 waiting for monitor entry [0x00007ffff15e5000] java.lang.Thread.State: BLOCKED (on object monitor) at LockTest.intrinsicLock(LockTest.java:9) - waiting to lock <0x00000007d6a33b10> (a LockTest) at LockTest$1.run(LockTest.java:11) at java.lang.Thread.run(Thread.java:662)
while lockTest.reentrantLock()
produce:
"My thread" prio=10 tid=0x00007fffec082800 nid=0x17e8 waiting on condition [0x00007ffff14eb000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007d6a33d30> (a java.util.concurrent.locks.ReentrantLock$FairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178) at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:201) at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262) at LockTest.reentrantLock(LockTest.java:22) at LockTest$2.run(LockTest.java:25) at java.lang.Thread.run(Thread.java:662)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With