Java SWT GUI 在长时间运行的后台进程期间对更新无响应

标签 java multithreading swt

使用的技术: java 1.6 SWT 图形用户界面

问题: 后台任务运行大约 60 分钟后,GUI 信息更新最终会停止(GUI 完全无响应)。

问题似乎与 GUI 更新有关,我不知道如何解决这种情况(查看了 Java 并发选项等)。优化线程定期使用处理信息更新 GUI 中的文本框。在我的测试过程中,此“更新”明显落后于控制台输出和数据库输出——假设优化执行了 4000 个优化步骤。控制台可能会报告优化步骤 1900 的工作情况(在数据库中确认),但 GUI 仍然输出来自步骤 700 的信息。

背景信息: 我正在运行机器学习优化任务并将该任务合并到 SWT GUI 中。该任务可能需要一个小时或更长时间才能完成,具体取决于参数。我将优化任务设计为一个单独的线程。 GUI 允许用户按下按钮来启动优化。 GUI 包括(为了简化)1) 任务表和 2) 用于在优化过程中提供反馈的 SWT 文本框。当每个不同的任务组完成时,任务表就会更新。 SWT 文本框输出更规则/频繁的反馈(很像 System.out,但使用线程通过 GUI EDI 线程更新文本框)。也就是说,我相信我至少使用了三个线程:1) GUI 线程,2) 用于 GUI 更新 (SWT) 的 aSync 线程,以及 3) 用于优化本身的后台线程。 (我提到这一点是因为 Java 并发教程明确指示长时间运行的任务必须在自己的线程中运行,以避免 GUI 死锁和饥饿。但是,即使我认为我这样做了,GUI 在长时间优化运行后仍然会停止-- 这就是我正在尝试解决的问题。因为优化运行需要很长时间才能完成,所以 GUI 停顿是一个主要问题 -- 在意识到 GUI 停顿之前损失了一个多小时。)

基本程序结构: GUI类-->为优化类启动一个单独的线程

优化类可以通过回调更新 GUI 类组件(使用 SWT asyncExec)

确认: 我可以确认后台线程完全运行--1)后​​台线程更新了几个数据库表并且所有表都完全彻底更新; 2) 直接从优化任务发送到 Eclipse 控制台的 System.out 输出显示优化线程完全运行。

此外,在测试过程中,如果我将优化设置缩减到大约 400 步,GUI 似乎运行良好。

相关代码: GUI类-- 更新 GUI 和 GUI 类中的代码(由优化类线程调用)--

public void setFeedback(final String workerthreadinfo, final boolean append) {
try{  
    Display.getDefault().asyncExec(new Runnable(){  
    public void run(){  
        if(!textfeedback.isDisposed() && textfeedback !=null){  
        if (append) {
                      textfeedback.setText(workerthreadinfo + "\n" +
                            textfeedback.getText()) ;
        } else {
            textfeedback.setText(workerthreadinfo) ;
        }  
         } 
    }  
    });
     } .....

GUI类中优化工作线程的实例化

private OptimizerWorkerThread workerthread = 
   new OptimizerWorkerThread(this) ;

GUI 类中的代码启动优化类(作为线程)

protected void optimize() {
    workerthread.go() ;
}

优化类-- 优化线程方法“链接”到GUI(guiwindow=上面的GUI类)

// ==================================================================
// GUI Update Methods
// ================================================================== 
public void updateFeedBackInfo(String update, boolean append) {
    guiwindow.setFeedback(update, append) ;
}

从优化线程回调 GUI 的示例

//GUI Feedback
this.updateFeedBackInfo("Saving optimization run record to database ... ", 
   APPENDTEXT ) ; // APPENDTEXT = boolean TRUE instructing GUI textbox to append

最佳答案

这听起来不太像线程问题。

如果您意外地在 GUI 线程中运行,则单击按钮后 GUI 将立即死机。所以我认为我们可以排除这种可能性。

您所描述的听起来更像是内存负载/性能问题。我强烈建议将 Visualvm 与您的应用程序连接,并特别注意不断增加的内存消耗。另外,使用 VisualVM 中包含的分析器可能会提示消耗大量 CPU 或内存的内容。

关于Java SWT GUI 在长时间运行的后台进程期间对更新无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10787081/

相关文章:

multithreading - 使用 Haskell 的 MVar 包,但使用 seq 强制执行严格性

multithreading - magic statics : similar constructs, 有趣的非显而易见的用途?

java - 如何动态创建SWT按钮及其 Action ?

java - 适用于 Eclipse SWT Text 的监听器是什么?

java - 我如何根据要替换的内容用单个项目替换多个项目

java - 如何迭代从对象派生的 ArrayList

java - 覆盖 OSMdroid 中的位置跟踪

c# - 是否允许在线程之间缓存/重用 Thread.GetNamedSlot?

java - 使用浮点类型重载方法

java - SWT + Maven + Eclipse = java.lang.UnsatisfiedLinkError : no swt-carbon-3346 or swt-carbon in swt. 库.path