自动检测悬挂线程

时间:2009-05-06 16:04:39

标签: java multithreading

我目前正在寻找一种在java中识别挂起线程的方法。谁知道最好的方法是什么?

目前我可以考虑两种可能的方法:

  1. 在应用程序的所有方法中定期调用(callback-)方法。这似乎是“有点”复杂而且难看......而且在调用外部方法时我无法控制......
  2. 一个额外的线程,它定期为所有线程生成线程转储(或者只是为了一些应该被监视的线程 - 因为我知道我想监视哪个线程)并分析结果(“线程仍在同一点上锁定相同的对象“,...)。 这可能有点危险,因为线程可能再次(!)处于同一点...... 顺便说一下 - 有一种简单的方法可以在Java 1.4中获取Thread转储(我不想调用外部应用程序)。我想用1.5或1.6有方法可以轻松做到这一点......
  3. 我猜这两种方法都不是一个很好的解决方案......所以你知道一种方法吗?

    正如我之前所说:我不想使用任何外部应用程序......

6 个答案:

答案 0 :(得分:2)

我发现当我们遇到卡住的线程时,我们的应用服务器通常会遇到性能问题。

我们采用低技术方法来确定线程卡在哪里。

我们向JVM发送几个kill -3信号以生成多个线程转储,然后分析输出以查找类似的跟踪,指示有问题的代码。

低技术和手册,但它有效。

答案 1 :(得分:1)

您可以使用jconsolejvisualvm附加到正在运行的流程。这两个工具都允许您查看Thread的堆栈跟踪和线程状态。

JVisualVM屏幕截图:

JVisualVM monitoring threads

答案 2 :(得分:0)

如果您正在寻找“自动”方式。除了在设计过程中花费更多时间外,没有好的解决方案。如果你有“悬挂”的线程,那么它们没有正确关闭。我会花时间研究如何在上下文中关闭它们,而不是试图编写一个寻找过时线程的例程/线程。

答案 3 :(得分:0)

这只是一个想法:

保留关于线程开始时间和线程引用的集中(同步)类信息。例如,ConcurrentHashMap(从现在开始CHM)。

过了一些(保守的)时间你可以向CHM请求那个线程(或者你怀疑它可能被绞死的watever线程)因为它的开始时间。如果线程还活着,你可以(保守地)确定它被绞死了。

你可以更进一步,保持线程的堆栈跟踪,如前所述。

答案 4 :(得分:0)

这里的问题是“悬挂线程”的含义以及在什么情况下。

是在一个大的J2EE服务器(可能会发现自己)或一个小的Java程序中,你产生了大量的线程?如果是后者,请考虑调查Java 5+中的并发实用程序,它允许您控制Runnables和Callables。

答案 5 :(得分:0)

如果你有竞争条件,那么带来额外的资源(即安装JDK并使用jps和jstack)来解决这个问题肯定是合理的......

也就是说,如果您在容器外运行应用程序,则可以从控制台运行应用程序并按ctrl + break(Windows)以获取线程转储。或者在* nix上杀死-3。

但根据您在评论中的回答,听起来这可能是在某种应用服务器中运行。

问题在于,你所做的任何事情都会给这种情况带来更多的不确定性。您如何知道您的死锁监视器本身不应对死锁负责?

另一种选择是引入系统输入的记录,然后根据这些输入重新播放系统中发生的事情。如果您的客户基本上说他们不会帮助您解决您的竞争状况,那么您需要在自己的测试环境中自己找到它。模拟客户站点的负载条件是尝试此操作的一种方式。

但实际上,我建议你使用它们来安装JDK(所以你可以使用jstack),或者某种类型的JRE 1.4监控应用程序(哎呀,确保他们的app服务器还没有提供这个有点事。)