0

我看到奇怪的行为,我不知道如何进一步了解并希望有人能提供帮助。

背景:我有一个查询需要很长时间才能返回结果,因此我没有让用户在请求时直接等待数据,而是定期通过 Timer 对象执行此查询并将结果存储在静态变量中。因此,当用户请求数据时,我总是从静态变量中提取数据,从而使响应几乎是即时的。到目前为止,一切都很好。

问题:然而,我看到的行为是,如果我在后台(定时器)请求开始查询数据时请求数据,我的用户的请求会等待数据返回后再响应——强迫用户等待。就好像 tomcat 的行为与线程同步(我知道不是——它只是看起来那样)。

这是在生产环境中,并且在大多数情况下,一切都很好,但对于用户来说,有时网站只是为他们挂起并且他们觉得它不可靠(嗯,在某种意义上它是)。

我所做的:由于对数据的请求是在静态方法中,我想“啊哈!线程已同步,这导致了延迟!” 所以我把我所有的静态方法都拿出来,删除了同步并强制每个调用实例化它自己的对象来检索数据(以保持线程安全)。静态变量的信号量也没有任何同步。

我还安装了 javamelody 来尝试了解正在发生的事情,但到目前为止还没有什么新鲜事。我注意到很多(大多数)线程处于“等待”状态,但它们也有 0 毫秒的用户和 CPU 时间,所以不要认为这指向任何东西(?)。

运行 Tomcat 5.5(无 apache 层)、struts 2、Java 1.5

如果有人知道为什么对静态变量的简单请求会挂起更长的后台进程,我将不胜感激!或者,如果您知道我如何获得洞察力,那也很棒。

谢谢!

4

2 回答 2

0

一种可能的解释是,由于长时间运行的查询引起的数据库锁定(或其他原因),线程实际上在数据库级别阻塞。

弄清楚发生了什么的方法是准确找出被阻塞的线程阻塞的位置。可以通过向 JVM 发送 SIGQUIT(或等效项)来生成线程转储,并包含所有 Java 线程堆栈的堆栈跟踪。或者,您可以通过附加调试器等来获得相同的信息(以及更多信息)。无论哪种方式,每个堆栈顶部框架的类名和行号应该允许您查看源代码并(至少)弄清楚正在发生什么样的锁定或阻塞。

于 2012-09-01T00:15:34.540 回答
0

对于那些想知道的人,我最终找到了 VisualVM ( http://visualvm.java.net/download.html )。这是完美的。我像往常一样从 Eclipse 运行 Tomcat,它出现在 VisualVM 客户端中。右键单击 tomcat 图标,选择 Thread Dump,然后,我已经搞定了。

谢谢大家的帮助和指向正确方向的指示!

于 2012-09-06T02:13:51.890 回答