当然有可能。您也可以在运行时检查!
第一步是获取线程转储。这是三种方法:
- 如果您在VisualVM中打开该过程,然后转到“线程”选项卡,它将告诉您它是否检测到这种僵局。然后,您可以进行线程转储(那里有一个按钮),它将告诉您每个线程在做什么,以及它拥有的任何锁以及任何锁定(如果有)试图获取的锁。
- 在Linux或Mac上,您可以通过发行获得堆栈
kill -3 <pid>
, , 在哪里 <pid>
是您的Java过程ID。它会将同一线程转储到stderr。该线程转储的底部还将包含其检测到的僵局的摘要。我不知道该如何在窗户上执行此操作。
- 你也可以调用
jstack <pid>
, ,它将将线程转储打印到stdout( jstack
'S stdout,而不是原始的Java过程')。
我写了一个僵局并运行的示例程序(请参阅 我的要点)。线程转储的相关部分是:
Found one Java-level deadlock:
=============================
"Thread-2":
waiting for ownable synchronizer 7f42b0f38, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "Thread-1"
"Thread-1":
waiting for ownable synchronizer 7f42ba170, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "Thread-2"
相关线程状态是:
"Thread-2" prio=5 tid=7fc01c911000 nid=0x113d18000 waiting on condition [113d17000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <7f30c3528> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
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$NonfairSync.lock(ReentrantLock.java:186)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
at Locky$Boomer.run(Locky.java:22)
at java.lang.Thread.run(Thread.java:680)
Locked ownable synchronizers:
- <7f30c3558> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"Thread-1" prio=5 tid=7fc01d06c800 nid=0x113c15000 waiting on condition [113c14000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <7f30c3558> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
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$NonfairSync.lock(ReentrantLock.java:186)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
at Locky$Boomer.run(Locky.java:22)
at java.lang.Thread.run(Thread.java:680)
Locked ownable synchronizers:
- <7f30c3528> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
这将不起作用 全部 僵局。例如,由于等待外部资源而导致的僵局不会被捕获。但这会抓住 Lock
- 基于僵局 synchronized
- 基于基础。