编程死锁检测在Java
-
12-09-2019 - |
题
如何程序的检测死锁发生在一个Java程序?
没有正确的解决方案
其他提示
您可以做到这一点编程方式使用ThreadMXBean
附带的JDK:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.
if (threadIds != null) {
ThreadInfo[] infos = bean.getThreadInfo(threadIds);
for (ThreadInfo info : infos) {
StackTraceElement[] stack = info.getStackTrace();
// Log or store stack trace information.
}
}
显然,你应该尝试找出哪个线程执行此死锁检查 - 否则,如果该线程死锁它将无法运行检查
顺便提及,这是JConsole的是使用下盖什么。
调查一种有用的提示:
如果你能赶上应用红色手,并怀疑僵局已经出现,去按“Ctrl-BREAK”在java.exe的控制台窗口(或“按Ctrl - \”在Solaris / Linux)的。 JVM将转储全部线程的当前状态和堆栈跟踪,找出死锁,准确地描述它们。
它看起来是这样的:
Full thread dump Java HotSpot(TM) Client VM (1.5.0_09-b03 mixed mode):
"[Test Timer] Request Queue" prio=6 tid=0x13d708d0 nid=0x1ec in Object.
wait() [0x1b00f000..0x1b00fb68]
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at library.util.AsyncQueue.run(AsyncQueue.java:138)
- locked <0x02e70000> (a test.server.scheduler.SchedulerRequestQueue)
...
Found one Java-level deadlock:
=============================
"Corba service":
waiting to lock monitor 0x13c06684 (object 0x04697d90, a java.lang.Object),
which is held by "[Server Connection] Heartbeat Timer"
"[Server Connection] Heartbeat Timer":
waiting to lock monitor 0x13c065c4 (object 0x0467e728, a test.proxy.ServerProxy), which is held by "Corba service"
Java stack information for the threads listed above:
===================================================
"Corba service":
at test.proxy.ServerProxy.stopHBWatchDog(ServerProxy:695)
- waiting to lock <0x04697d90> (a java.lang.Object)
...
可以检测僵持线程编程方式使用ThreadMXBean的class.Here是代码,
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long ids[] = bean.findMonitorDeadlockedThreads();
if(ids != null)
{
ThreadInfo threadInfo[] = bean.getThreadInfo(ids);
for (ThreadInfo threadInfo1 : threadInfo)
{
System.out.println(threadInfo1.getThreadId()); //Prints the ID of deadlocked thread
System.out.println(threadInfo1.getThreadName()); //Prints the name of deadlocked thread
System.out.println(threadInfo1.getLockName()); //Prints the string representation of an object for which thread has entered into deadlock.
System.out.println(threadInfo1.getLockOwnerId()); //Prints the ID of thread which currently owns the object lock
System.out.println(threadInfo1.getLockOwnerName()); //Prints name of the thread which currently owns the object lock.
}
}
else
{
System.out.println("No Deadlocked Threads");
}
点击这里关于如何检测更多信息的死锁线程。
JArmus 是用于检测和避免死锁的库。它包括支持:
Thread.join
,CyclicBarrier
,CountDownLatch
,Phaser
和
ReentrantLock
。
要使用JArmus您需要的仪器代码。无论是通过其仪表类中的一个或与JArmus instrumentar jarmusc
自动
java -jar jarmusc.jar yourprogram.jar checkedprogram.jar
输入yourprogram.jar
是要检查程序。
输出与检查相同的程序来自动找到任何死锁。
壁垒需要一些帮助
与类CyclicBarrier
,CountDownLatch
,Phaser
验证死锁是有点麻烦---例如,JConsole的不能检测这些类型的死锁。 JArmus需要您的一点帮助:你必须指定哪些线程同步的影响,我们称这些的注册的线程。
只要可能,注册该线程必须标记本身。一个很好的纪念注册线程是开头方法Runnable.run
。
JArmus.register(latch);
实施例
下面的程序的死锁被正确识别通过 JArmus:
final CountDownLatch latch = new CountDownLatch(2);
final CyclicBarrier barrier = new CyclicBarrier(2);
final Queue<Exception> exceptions = new ArrayDeque<>();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
JArmus.register(barrier); // do not forget to register!
JArmus.register(latch); // do not forget to register!
latch.countDown();
latch.await();
barrier.await();
} catch (Exception e) {
exceptions.add(e);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
JArmus.register(barrier); // do not forget to register!
JArmus.register(latch); // do not forget to register!
barrier.await();
latch.countDown();
latch.await();
} catch (Exception e) {
exceptions.add(e);
}
}
});
t1.start();
t2.start();
如果你不需要编程检测可以通过这样做的 JConsole的强>;线程选项卡上有一个“死锁检测”按钮。在此JDK6检测两个固有监视器和j.u.c
Lock
s锁
经由$JAVA_HOM/bin/jconsole
命令运行了JConsole的
在魔术发生在ThreadMonitor.findDeadlock()
:
public boolean findDeadlock() {
long[] tids;
if (findDeadlocksMethodName.equals("findDeadlockedThreads")
&& tmbean.isSynchronizerUsageSupported()) {
tids = tmbean.findDeadlockedThreads();
if (tids == null) {
return false;
}
System.out.println("Deadlock found :-");
ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);
for (ThreadInfo ti : infos) {
printThreadInfo(ti);
printLockInfo(ti.getLockedSynchronizers());
System.out.println();
}
} else {
tids = tmbean.findMonitorDeadlockedThreads();
if (tids == null) {
return false;
}
ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);
for (ThreadInfo ti : infos) {
// print thread information
printThreadInfo(ti);
}
}
return true;
}
这个调用,其具有在Java中5和6不同的名称(因此外ThreadMXBean
)的if()
的API。
的代码示例还允许中断锁,因此甚至可以打破僵局。
的Tempus-福吉特还实现其与编程螺纹倾倒类一起。它使用上述的mbean机构实现,并且在提供的下降,外的现成超级骗子溶液。
如果你希望它在运行时进行,您可以使用看门狗为这一点。