5

多线程应用程序冻结。可能是死锁造成的。如果是,那么我们如何找到死锁的原因?有什么工具和策略可以系统地做到这一点吗?

4

3 回答 3

8
  1. 如果可能,请使用无锁数据结构,例如ConcurrentLinkedQueue。根据定义,无锁数据结构不会导致死锁。

  2. 始终以相同的顺序获取锁。如果你的资源是A、B、C,那么所有线程都应该按照A -> B -> C,或者A -> C,或者B -> C等顺序获取它们。如果一个线程获取,就会发生死锁它们按照 A -> B -> C 的顺序获取,而另一个线程按照 C -> B -> A 的顺序获取它们。

  3. 使用锁定超时 - 如果计时器到期,则线程释放其锁定。请务必在发生这种情况时进行记录,以便您可以重新检查您的锁定顺序。

  4. 使用死锁检测

于 2013-04-10T21:34:15.860 回答
7

我们如何找到死锁的原因?

  • 使用程序

java.lang.management.ThreadMXBean是找出Java死锁线程的答案。这是简短的代码演示:

import java.lang.management.*;
class  DeadLockDetect
{
    public void findDeadLocks()
    {
        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
        long[] ids = tmx.findDeadlockedThreads();
        if (ids != null )
        {
            ThreadInfo[] infos = tmx.getThreadInfo(ids,true,true);
            System.out.println("Following Threads are deadlocked");
            for (ThreadInfo info : infos)
            {
                System.out.println(info);
            }
        }
    }
}
  • 使用工具
    JConsole 是一种工具,它可以告诉您代码中运行的线程的几乎所有信息。
于 2013-04-10T21:34:25.453 回答
4

我要做的第一件事是使用 jstack 获取线程堆栈,它是 JDK 附带的。

用法 :jstack <pid>

在这里您可以看到所有正在运行的线程的当前状态。你可以看到线程等待锁等。

文档:http ://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.html

在这里您可以看到存在哪些不同的线程状态:http: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.State.html

于 2013-04-10T21:34:08.867 回答