【问题标题】:java GUI unresponsive for several secondsjava GUI无响应几秒钟
【发布时间】:2011-08-12 16:50:57
【问题描述】:

我们有一个 java 客户端/服务器应用程序,其中的 GUI 定期(每半小时)平均 2 到 10 秒无响应。点击不同按钮只会在挂起几秒钟后生效。

我一开始以为是 GC 问题,但调查证明这方面没有问题。

我更确信这是线程问题,图形线程有时会阻塞。

如何检查图形线程的状态以在我的日志中见证其“无响应”?我想我可以每隔一秒左右从一个不同的线程检查它的状态,但是怎么做呢?轮询哪个变量?

关于如何解决这个问题的任何其他想法?

谢谢

【问题讨论】:

  • 能把相关代码分享给我们吗?
  • 好吧,整个想法是调试一个相当大的应用程序。代码的问题部分可能在任何地方,我显然无法发布整个内容。试图在日志中见证问题(而不是依赖我的用户“感觉”)以继续前进。
  • 你怎么知道不是另一个进程让 JVM 挨饿?

标签: java multithreading user-interface thread-safety


【解决方案1】:

您可以向 Java 进程发出kill -QUIT(以及在 Windows 上等效的东西),这将导致所有线程将其堆栈跟踪转储到 STDOUT,因此您可以看到发生了什么。这也显示了哪些线程正在持有锁(同步块)以及哪些正在等待。

【讨论】:

  • 目前无法在测试平台上重现该问题,而且我不能在软件在生产中运行时直接终止该软件。我需要插入一些简单的日志记录,以便开始见证这个线程发生了什么。为了确认问题已解决,这也是必要的。
  • @Bastien: kill -QUIT 不会停止 GUI;它只是转储有关每个正在运行的线程的信息。
  • 这确实是一个线程问题,我们使用多种工具(例如您推荐的方法)进行了调试。
【解决方案2】:

如果您无法在测试中重现问题,并且无法关闭生产,那么您的问题就没有简单的答案。

似乎您可能遇到更大的问题,必须使用某种分析工具进行诊断。我们使用 JProbe 和 JProfiler 并且很幸运。

在最坏的情况下,您可以使用 JMX 来编写您自己的代码,按照此链接的内容执行某些操作。过去它对我非常有用。

http://www.javamex.com/tutorials/profiling/profiling_java5_threads_methodology.shtml

【讨论】:

    【解决方案3】:

    要了解 ui 线程被阻塞了多长时间,您可以执行以下操作,

    ScheduledThreadPoolExecutor executor = ....
    executor.scheduleAtFixedRate(new Runnable(){ 
       public void run() {testEventThread();}}, 5, 5, TimeUnit.SECONDS);
    
    void testEventThread() {
       final long now = System.currentTimeMillis();
       SwingUtilities.invokeLater(new Runnable() {
           public void run() {
                 System.out.println("event thread took:" + (System.currentTimeMillis()- now) + " to respond");
           }
       });
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-25
      • 2013-12-08
      • 1970-01-01
      • 2022-12-12
      相关资源
      最近更新 更多