Java中的死锁检测

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/217113/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:32:06  来源:igfitidea点击:

Deadlock detection in Java

javamultithreadingdeadlock

提问by israkir

Long time ago, I saved a sentence from a Java reference book: "Java has no mechanism to handle deadlock. it won't even know deadlock occurred." (Head First Java 2nd Edition, p.516)

很久以前,我从Java参考书中保存了一句话:“Java没有处理死锁的机制。它甚至不会知道死锁发生了。” (Head First Java 第二版,第 516 页)

So, what is about it? Is there a way to catch deadlock case in Java? I mean, is there a way that our code understands a deadlock case occurred?

那么,它到底是怎么回事?有没有办法在 Java 中捕获死锁情况?我的意思是,有没有办法让我们的代码理解发生了死锁情况?

回答by Steve K

JConsoleis able to detect deadlocks in a running application.

JConsole能够检测正在运行的应用程序中的死锁。

回答by Paul Tomblin

Not exactly what you asked, but when a deadlock doesoccur, you can do a "kill -3" on the process id and it dumps a thread dump to stdout. Also, the 1.6 jvm has some tools to do the same thing in a gui manner.

不完全是您所要求的,但是当确实发生死锁时,您可以对进程 ID 执行“kill -3”并将线程转储转储到标准输出。此外,1.6 jvm 有一些工具可以以 gui 方式做同样的事情。

回答by Paul Croarkin

If you are running from the command-line and you suspect that you are deadlocked, try ctrl+break in windows (ctrl+\ in unix) to get a thread dump. See http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/gbmps.html

如果您从命令行运行并且您怀疑自己已死锁,请尝试在 windows 中使用 ctrl+break(在 unix 中为 ctrl+\)以获取线程转储。见http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/gbmps.html

回答by luke

In general java does not offer deadlock detection. The synchronized keyword and built in monitors make it somewhat more difficult to reason about deadlock than in languages with explicit locking.

一般来说,java 不提供死锁检测。与使用显式锁定的语言相比,synchronized 关键字和内置监视器使得推断死锁更加困难。

I would suggest migrating to using java.util.concurrent.Lock locks and the like in order to make your locking schemes easier to reason about. In fact you could easily make your own implementation of the lock interface with deadlock detection. The algorithm is to basically traverse the lock dependency graph and look for a cycle.

我建议迁移到使用 java.util.concurrent.Lock 锁等,以使您的锁定方案更容易推理。事实上,您可以轻松实现自己的带有死锁检测功能的锁接口。算法基本上就是遍历锁依赖图,寻找一个循环。

回答by Alex Miller

JDK 5 and 6 will dump held lock information in a full thread dump (obtained with kill -3, jstack, jconsole, etc). JDK 6 even contains information about ReentrantLock and ReentrantReadWriteLock. It is possible from this information to diagnose a deadlock by finding a lock cycle: Thread A holds lock 1, Thread B holds lock 2, and either A is requesting 2 or B is requesting 1. From my experience, this is usually pretty obvious.

JDK 5 和 6 将在完整的线程转储中转储持有的锁信息(通过 kill -3、jstack、jconsole 等获得)。JDK 6 甚至包含有关 ReentrantLock 和 ReentrantReadWriteLock 的信息。根据这些信息,可以通过查找锁周期来诊断死锁:线程 A 持有锁 1,线程 B 持有锁 2,并且 A 正在请求 2 或 B 正在请求 1。根据我的经验,这通常很明显。

Other analysis tools can actually find potential deadlocks even if they don't occur. Thread tools from vendors like OptimizeIt, JProbe, Coverity, etc are good places to look.

其他分析工具实际上可以发现潜在的死锁,即使它们没有发生。来自 OptimizeIt、JProbe、Coverity 等供应商的线程工具是不错的选择。

回答by user29480

Dr. Heinz Kabutz of JavaSpecialists has written an entertaining and informative newsletter issue on Java deadlocksand describes something called a ThreadMXBean in another newsletter issue. Between those, you should get a good idea of the issues and some pointers to doing your own instrumentation.

JavaSpecialists 的 Heinz Kabutz 博士撰写了一篇关于 Java 死锁的有趣且内容丰富的时事通讯,并在另一期时事通讯中描述了一种称为 ThreadMXBean 的东西。在这些之间,您应该对问题有一个很好的了解,并获得一些指导来进行自己的检测。

回答by paxdiablo

Deadlocks can be avoided if you follow a simple rule: have all threads claim and release their locks in the same order. In this way, you never get into a situation where a deadlock can occur.

如果您遵循一个简单的规则,就可以避免死锁:让所有线程以相同的顺序声明和释放它们的锁。通过这种方式,您永远不会陷入可能发生死锁的情况。

Even the dining philosophers problem can be seen as a violation of this rule as it uses relative concepts of left and right spoon which result in different threads using different allocation orders of the spoons. If the spoons were numbered uniquely and the philosophers all tried to get the lowest numbered spoon first, deadlock would be impossible.

甚至哲学家进餐问题也可以被视为违反此规则,因为它使用了左右勺子的相对概念,导致不同的线程使用不同的勺子分配顺序。如果勺子的编号是唯一的,而哲学家们都试图先得到编号最低的勺子,那么就不可能出现僵局。

In my opinion, prevention is better than cure.

在我看来,预防胜于治疗。

This is one of the two guidelines I like to follow to ensure threads work properly. The other is ensuring each thread is solelyresponsible for its own execution as it's the only one fully aware of what it's doing at any point in time.

这是我喜欢遵循的两个准则之一,以确保线程正常工作。另一个是确保每个线程单独负责自己的执行,因为它是唯一一个在任何时间点都完全了解自己在做什么的线程。

So that means no Thread.stopcalls, use a global flag (or message queue or something like that) to tell another thread you want action taken. Then let that thread do the actual work.

所以这意味着没有Thread.stop调用,使用全局标志(或消息队列或类似的东西)告诉另一个线程你想要采取行动。然后让该线程完成实际工作。

回答by WMR

If you are on Java 5 you can call the method findMonitorDeadlockedThreads()on the ThreadMXBean which you can get through a call of java.lang.management.ManagementFactory.getThreadMXBean(). This will find deadlocks caused by object monitors only. On Java 6 there's findDeadlockedThreads()which will also find deadlocks caused by "ownable synchronizers (for example ReentrandLockand ReentrantReadWriteLock).

如果您使用的是 Java 5,则可以调用findMonitorDeadlockedThreads()ThreadMXBean 上的方法,您可以通过调用java.lang.management.ManagementFactory.getThreadMXBean(). 这将仅找到由对象监视器引起的死锁。在 Java 6 上findDeadlockedThreads(),还会发现由“可拥有的同步器(例如ReentrandLockReentrantReadWriteLock)”引起的死锁。

Be aware that it will probably be expensive to call these methods, so they should be used for troubleshooting purposes only.

请注意,调用这些方法可能会很昂贵,因此它们应仅用于故障排除目的。

回答by staffan

Since JDK 1.5 there are very useful methods in the java.lang.managementpackage to find and inspect deadlocks that occurs. See the findMonitorDeadlockedThreads()and findDeadlockedThreads()method of the ThreadMXBeanclass.

从 JDK 1.5 开始,java.lang.management包中有非常有用的方法来查找和检查发生的死锁。请参阅类的findMonitorDeadlockedThreads()findDeadlockedThreads()方法ThreadMXBean

A possible way to use this is to have a separate watchdog thread (or periodic task) that does this.

使用它的一种可能方法是有一个单独的看门狗线程(或周期性任务)来执行此操作。

Sample code:

示例代码:

  ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
  long[] ids = tmx.findDeadlockedThreads();
  if (ids != null) {
     ThreadInfo[] infos = tmx.getThreadInfo(ids, true, true);
     System.out.println("The following threads are deadlocked:");
     for (ThreadInfo ti : infos) {
        System.out.println(ti);
     }
  }

回答by Scott Stanchfield

If you're debugging in eclipse, you can pause the application (select the app in the debug view and the little || button on the debug toolbar) and then it can report deadlocks.

如果您在 eclipse 中调试,您可以暂停应用程序(在调试视图中选择应用程序和调试工具栏上的小 || 按钮),然后它可以报告死锁。

See http://runnerwhocodes.blogspot.com/2007/10/deadlock-detection-with-eclipse.htmlfor an example.

有关示例,请参见http://runnerwhocodes.blogspot.com/2007/10/deadlock-detection-with-eclipse.html