0

我有一个运行大型应用程序的 Tomcat 服务器。它有两个类似于这个例子的类:

public abstract class ClassA {
  private static final Logger LOGGER = Logger.getLogger(ClassA.class);
  // ...
  public File methodA(ICancellable cancel) {
    URL request = new URL("an URL");
    LOGGER.debug("Calling ClassB.methodB(type)");
    File f = classB.methodB(request, "type", cancel);
    LOGGER.debug("The call to ClassB.methodB(type)"
                 + " returned the File==" + f);
    // ...
  }
}

public class ClassB {
  private static final Logger LOGGER = Logger.getLogger(ClassB.class);
  // ...
  public static synchronized File methodB(URL url, String type, 
                                          ICancellable cancel) 
  {
    final String thisMethodsName = "ClassB.methodB(url: " + url 
                           + ", type:" + type + ", cancel: " + cancel + ")";
    LOGGER.debug("Entering method: " + thisMethodsName);
    // ...
    return f;
  }
}

正如我在日志文件中看到的那样,该应用程序可以正常工作,并且ClassA.methodA()最初成功调用:ClassB.methodB()

[...]
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type)
14/02/2013 12:34:56 DEBUG ClassB:456 - Entering method: ClassB.methodB(url: anURL, type: type, cancel: @1234);
[...]
14/02/2013 12:34:56 DEBUG ClassA:125 - The call to ClassB.methodB(type) returned the File=="aFile".
[...]

我的问题是服务器工作一段时间后,它停止调用ClassB.methodB(). 应用程序挂起,它只是将其写入日志:

[...]
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type)

这是日志文件的最后一行。ClassB.methodB()实际上并没有被调用。

我怀疑这可能是由于打开的资源没有关闭,但我试图找到所有这样做的代码,并且在修复之后,它仍然会发生。

这可能是什么原因造成的?我怎样才能继续寻找原因?


JVM版本:1.6.0_13 Tomcat版本:6.0.18

4

2 回答 2

1

是否有可能存在涉及您未粘贴的某些代码的线程死锁错误?你的ClassB.methodB方法是synchronized。您可能有一些其他线程正在持有而不释放synchronized锁定ClassB.class,从而阻止正在执行日志记录的线程获取该锁定并进入该方法。

于 2013-02-14T12:15:52.230 回答
0
  1. 启用调试模式并在代码中分配断点。使用IDE(最好是eclipse)一步一步来。
  2. Eclipse 有诸如 findbugs 或 PMD 之类的插件来扫描代码并找出可能的错误。
  3. 手动检查每个条件、方法调用、循环以查看缺陷。

如果您已经编写了完整的应用程序,那么您就会知道在哪里查看。如果没有,最好检查所有写的

于 2013-02-14T12:20:50.903 回答