首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在长时间运行的后台过程中,Java对更新没有响应

在长时间运行的后台过程中,Java对更新没有响应
EN

Stack Overflow用户
提问于 2012-05-28 15:31:49
回答 2查看 1.8K关注 0票数 1

使用的技术:Java1.6SWTGUI

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

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

背景信息:我正在运行一个机器学习优化任务,并将该任务合并到SWT中。根据参数的不同,任务可能需要一个小时或更长时间才能完成。我将优化任务设计为一个单独的线程。GUI允许用户按下按钮启动优化。GUI包括(为了简化) 1)一个任务表和2)一个SWT文本框,用于在优化过程中进行反馈。当每个不同的任务组完成时,任务表将被更新。SWT文本框输出更有规律/更频繁的反馈(非常像System.out,但使用线程通过GUI EDI线程更新文本框)。也就是说,我至少使用了三个线程: 1) GUI线程,2)用于GUI更新的aSync线程,3)用于优化本身的后台线程。(我之所以提到这一点,是因为Java并发教程明确指出,长时间运行的任务必须在自己的线程中运行,以避免GUI死锁和饥饿。然而,尽管我认为我做到了这一点,但是GUI在经过长时间的优化运行之后仍然处于停滞状态--这就是我试图修复的地方。由于优化运行需要很长时间才能完成,GUI失速是一个主要问题--在实现GUI停滞之前损失了一个多小时。

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

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

确认:i可以确认后台线程完全运行--1)后台线程更新多个数据库表,所有表都完全更新;2)直接从中发送到控制台的优化任务的System.out输出显示优化线程完全运行。

此外,在测试期间,如果我将优化集缩小到大约400步,GUI似乎运行良好。

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

代码语言:javascript
运行
复制
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类中优化工作线程的实例化

代码语言:javascript
运行
复制
private OptimizerWorkerThread workerthread = 
   new OptimizerWorkerThread(this) ;

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

代码语言:javascript
运行
复制
protected void optimize() {
    workerthread.go() ;
}

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

代码语言:javascript
运行
复制
// ==================================================================
// GUI Update Methods
// ================================================================== 
public void updateFeedBackInfo(String update, boolean append) {
    guiwindow.setFeedback(update, append) ;
}

从优化线程调用GUI的示例

代码语言:javascript
运行
复制
//GUI Feedback
this.updateFeedBackInfo("Saving optimization run record to database ... ", 
   APPENDTEXT ) ; // APPENDTEXT = boolean TRUE instructing GUI textbox to append
EN

回答 2

Stack Overflow用户

发布于 2012-05-28 17:51:12

这听起来不像一个线程问题。

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

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

票数 1
EN

Stack Overflow用户

发布于 2012-08-02 19:54:51

溶液增编:

在此应用程序的最终测试过程中,我更仔细地确定了GUI的明显来源。所谓GUI慢下来,我指的是复制2500个文件之间的区别.慢下来的问题需要将近20分钟才能完成.应用修复后,相同的文件需要不到1分钟的时间复制。

问题副本通过Worker处理。工作线程定期更新GUI。更新包括一个ProgressBar更新和一个文本框更新。

文本框更新似乎是问题的根源。我想要的是一个文本框PREPENDS --状态更新信息--比如“复制文件C:/hello.txt”--而不是附加(可在SWT中找到)。为了创建我所使用的人造代码(在一个单独的线程中):

代码语言:javascript
运行
复制
textfeedback.setText(workerthreadinfo + "\n" + textfeedback.getText()) ;

这一小块代码似乎是慢下来的罪魁祸首--也许很容易看出原因。在每个文件副本上,复制整个文本框内容,然后将新信息加到文本框中。在复制了大约700个文件后,它开始陷入停滞(您可以明显地看到慢下来),并在之后继续恶化。

尽管我对此不满意,但修复方法是使用SWT TextBox append()方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10787081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档