线程被卡在Thread.join()中,即使其他线程已经终止

3

我们的Java应用程序启动一个工作线程(使用Thread.start())。之后不久,它在工作线程上调用Thread.join()。工作线程执行一些操作并终止。第一个线程退出对join()的调用,然后顺利地继续执行。这是标准的做法:

Thread t = new WorkerThread();
t.start();

// Blah blah

t.join();

class WorkerThread extends Thread {
    public void run() {
        // Do some stuff
    }
}

至少理论上是这样的,而且在我们能够重现的任何情况下都是这样的。但我们有一个客户一直遇到麻烦。
使用PsiProbe查看线程时,他们会看到工作线程被创建。它运行了一段时间,但过了一段时间后就从线程列表中消失了。这发生在意料之外的时间(基于与工作线程相关的其他事件的时间)。主线程永远不会走出join()调用。
这似乎违反了join()的约定,并向我暗示了某种JVM级别的错误。有没有人见过这样的行为,或者有什么想法可以引起它?
编辑3-3-11:
我仍在等待客户的确定性数据,但似乎我并不真正知道我所认为的:主线程可能根本没有在join()中阻塞,而是在它之前的某个点上。
无论如何,感谢大家提供的想法。

3
好的,你执行的是thread.join()而不是t.join(),或者你只是打错了吗? - dontocsata
3
我会在工作线程中添加日志记录,并在启动/加入调用之前/之间/之后添加日志语句。另一种解决方案是使用超时调用join(long millis)。即使存在JVM级别的错误,这也可以解决问题。 - Petro Semeniuk
@Stephen C - 现在看来这可能是JVM问题,我需要获取具体版本的信息。它正在JBoss AS 4.2.3下运行(我想),如果那有关系的话。 - Aron
@Petro,我很想在其中加入一些有针对性的日志记录,但短期内很难有机会让它们在新版本中运行。 - Aron
知道了。然后你可以要求他们使用JDK提供的jstack工具而不是PsiProbe。它会提供运行线程的堆栈跟踪信息。有可能是PsiProbe本身存在Bug,导致无法正确显示'正在运行的'线程。 - Petro Semeniuk
显示剩余10条评论
1个回答

0

快速搜索Java Bugs Database没有找到与您的症状相匹配的内容。但是,进行更广泛的搜索是值得的。


然而,值得注意的是,JVM漏洞只是许多可能理论之一(请参见评论),目前几乎没有任何理论证据。如果我是你,我会:

  1. 弄清楚客户的平台是什么
  2. 在Java错误数据库中搜索任何已知的错误,看是否与观察到的症状相匹配(如有)。
  3. 如果找到一个看起来像“命中”的错误,请进一步评估它,尝试确认它确实是客户的问题,并查看是否有任何缓解方法。
  4. 此外...
    • 查看其他可能的理论;例如,请参见上文
    • 尝试弄清楚客户的安装与其他没有此问题的人有何不同
    • 添加更多监视,并尝试让客户使用该版本。

(在最后一个要点上,可能需要向客户指出显而易见的事情。如果他们想修复错误,他们可能需要做额外的工作来帮助您跟踪错误,例如安装运行“实验性”应用程序版本一段时间。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接