java中的编程死锁检测
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1102359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatic deadlock detection in java
提问by
How can I programmaticallydetect that a deadlock has occurred in a Java program?
如何以编程方式检测 Java 程序中是否发生了死锁?
回答by RichardOD
You might want to consider IBM's MTRAT. Prevention is better than cure after all. The Multicore Software Development Kitalso comes with a deadlock detection tool.
您可能需要考虑IBM 的 MTRAT。毕竟预防胜于治疗。在多核软件开发工具包还带有一个死锁检测工具。
回答by Artem Barger
回答by Nicolas Simonet
One useful hint for investigation:
一个有用的调查提示:
If you can catch the application red handed and suspect a deadlock has occurred, go and press "Ctrl-Break" in the java.exe console window (or "Ctrl-\" on Solaris/Linux). The jvm will dump the current status and stack trace of all threads, find out dead locks and precisely describe them.
如果您能发现应用程序并怀疑发生了死锁,请在 java.exe 控制台窗口中按“Ctrl-Break”(或在 Solaris/Linux 上按“Ctrl-\”)。jvm 将转储所有线程的当前状态和堆栈跟踪,找出死锁并精确描述它们。
It will look something like this:
它看起来像这样:
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)
...
回答by oxbow_lakes
If you don't require programmatic detection you can do this via the JConsole; on the thread tab there is a "detect deadlock" button. In JDK6 this detect locks for both intrinsic monitors and j.u.c
Lock
s
如果您不需要编程检测,则可以通过JConsole执行此操作;在线程选项卡上有一个“检测死锁”按钮。在 JDK6 中,这会检测内部监视器和j.u.c
Lock
s 的锁
Run up the JConsole via the $JAVA_HOM/bin/jconsole
command
通过$JAVA_HOM/bin/jconsole
命令运行 JConsole
回答by Adamski
You can do this programmatically using the ThreadMXBean
that ships with the JDK:
您可以使用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.
}
}
Obviously you should try to isolate whichever thread is performing this deadlock check - Otherwise if that thread deadlocks it won't be able to run the check!
显然,您应该尝试隔离正在执行此死锁检查的线程 - 否则,如果该线程死锁,它将无法运行检查!
Incidentally this is what JConsole is using under the covers.
顺便说一句,这就是 JConsole 在幕后使用的内容。
回答by Toby
tempus-fugitalso implements it along with a programmatic thread dumping class. It's implemented using the mbean mechanism mentioned above and offers a drop in, out-of-the-box super duper solution.
tempus-fugit还将它与编程线程转储类一起实现。它是使用上面提到的 mbean 机制实现的,并提供了一个即用型的、开箱即用的超级骗子解决方案。
回答by Aaron Digulla
There is code here: http://www.java2s.com/Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm
这里有代码:http: //www.java2s.com/Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm
The magic happens in ThreadMonitor.findDeadlock()
:
神奇发生在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;
}
This calls an API of the ThreadMXBean
which has a different name in Java 5 and 6 (hence the outer if()
).
这将调用ThreadMXBean
在 Java 5 和 6 中具有不同名称的 的 API (因此是外部的if()
)。
The code example also allows to interrupt the locks, so you can even break the deadlock.
该代码示例还允许中断锁定,因此您甚至可以打破死锁。
回答by Tiago Cogumbreiro
JArmusis a library for deadlock detection and avoidance. It includes support for:
Thread.join
, CyclicBarrier
, CountDownLatch
, Phaser
, and
ReentrantLock
.
JArmus是一个用于死锁检测和避免的库。它包括支持:
Thread.join
,CyclicBarrier
,CountDownLatch
,Phaser
,和
ReentrantLock
。
To use JArmus you need to instrument your code. Either through one of its instrumented classes or automatically with the JArmus instrumentar jarmusc
.
要使用 JArmus,您需要检测您的代码。通过其检测类之一或自动使用 JArmus 工具jarmusc
。
java -jar jarmusc.jar yourprogram.jar checkedprogram.jar
java -jar jarmusc.jar yourprogram.jar checkedprogram.jar
The input yourprogram.jar
is the program you want to check.
The output is the same program with checks to automatically find any deadlock.
输入yourprogram.jar
是您要检查的程序。输出是同一个程序,带有自动查找任何死锁的检查。
Barriers need some help
障碍需要一些帮助
Verifying deadlocks with classes CyclicBarrier
, CountDownLatch
, Phaser
is a bit tricky --- for example, JConsole cannot detect these types of deadlocks. JArmus needs a little help from you: you must specify which threads are influencing synchronization, we call these registeredthreads.
验证死锁与类CyclicBarrier
,CountDownLatch
,Phaser
是有点麻烦---例如,JConsole的不能检测这些类型的死锁。JArmus 需要您的一些帮助:您必须指定哪些线程正在影响同步,我们将这些线程称为注册线程。
As soon as possible, the thread must mark itself as registered. A good place to mark registered threads is at the beginning method Runnable.run
.
JArmus.register(latch);
线程必须尽快将自己标记为已注册。标记注册线程的一个好地方是在开始方法Runnable.run
。
JArmus.register(latch);
Example
例子
The following program that deadlocks is correctly identified by JArmus:
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();
回答by user2485429
You can detect the deadlocked threads programmatically using ThreadMXBean class.Here is the code,
您可以使用 ThreadMXBean 类以编程方式检测死锁线程。这是代码,
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");
}
Click herefor more info on how to detect the deadlocked threads.
单击此处了解有关如何检测死锁线程的更多信息。