2010-01-28 40 views
0

我有一个java程序,具有多线程。我的问题是,我有时会超时。 因为我有一些unix的东西,我看不到超时或/和锁定在哪里。问题在于,这不会每天晚上发生,只是不时发生。 实际上,一个unix组件(lsf)会终止线程(如果超过15分钟)。因为我看不出问题在哪里,所以我想知道是否有人有任何想法。 有没有机会启动另一个java的东西,当我有一个锁,写一个日志文件?如果,是的,会是什么?Java多线程 - 检测自动锁定线程

+1

正如有人曾经写的,多线程编程是95%思维和5%编写代码。所以更好的重新思考所有可能的种族和死锁情况。 – Bozho 2010-01-28 15:24:09

+0

这是一个现有的非常大的应用程序。不可能考虑所有情况。我到达时已经准备好了。 – 2010-01-28 15:33:16

回答

3

jstack是一个命令行程序,您可以用它来反省正在运行的java程序。它会打印出每个线程的堆栈跟踪,告诉你它是否被锁定,甚至检测到死锁。这可以帮助您以交互方式调试问题。

如果你想在你的程序中获得这些数据,你可以拨打Thread.getAllStackTraces()这将得到你所有的线程和他们的堆栈跟踪列表,所以你可以看到线程在哪里和他们的状态,如果你想'做如果某个线程被锁定,就像写入日志文件一样。

+0

问题是我没有经常遇到这个问题。 所以,我正在考虑类似于每次有锁时写入一些日志的代码片段和方法名称。 这样,在早上我可以分析日志,看看是否有锁,如果是的话,它在哪里。 但我不知道该怎么做。 – 2010-01-28 15:28:35

+0

这就是JCarder所做的(请参阅我的主要回复) – Rich 2010-01-28 15:31:03

+0

+1感谢提及Thread.getAllStackTraces() – stacker 2010-01-28 16:18:09

4

如果您必须让应用程序继续运行并且在错误的时间处于死锁状态,那么您可能从JCarder(它是您告诉Java使用的代理程序)中获得一些好处。程序运行完毕后,它会输出各种诊断文件,然后可以将其转换为图形以显示死锁。

另外,通过诸如Findbugs之类的东西运行你的代码,这可能会指出一个微妙的死锁情况,否则你没有注意到。

+0

如果应用程序。肯定会造成死锁,不太可能干净地终止。在能够产生诊断之前,JCarder是否依靠彻底的终止? – Adamski 2010-01-28 15:41:37

+0

这是一个代理,所以它倾向于能够处理大多数正常终止。 OP的问题可能在于机器如何选择杀死这个过程 - 如果它不是'JCarder友好'的方式,那么它可能是没用的。 – Rich 2010-01-28 15:45:38

+0

+1很酷的工具,希望我永远不需要它 – stacker 2010-01-28 16:20:44

1

除了jstack你可以检查出JConsole,这是一个GUI应用程序,允许您检测死锁,监视线程/内存/ CPU使用率,等它附带的JDK。

JConsole在内部使用ThreadMXBean,您还可以使用它编程检测死锁;例如我通常安排在我的服务器应用程序以定期调用下面的代码守护线程:

private void detectDeadlocks() { 
    logger.info("Checking for deadlocks."); 
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 

    long[] threadIds = threadMXBean.findDeadlockedThreads(); 

    if (threadIds == null || threadIds.length == 0) { 
     logger.info("No deadlocks found."); 
    } else { 
     StringBuilder sb = new StringBuilder(); 

     for (long threadId : threadIds) { 
      ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId); 

      if (sb.length() > 0) { 
       sb.append(", "); 
      } 

      sb.append(threadInfo.getThreadName()).append(" (ID: ").append(threadId).append(')'); 
     } 

     logger.severe("Blocked Threads: " + sb); 
     // Raise alert here, etc. 
    } 
}