使用的技术: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类中的代码(这由优化类线程调用)--
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
发布于 2012-05-28 17:51:12
这听起来不像一个线程问题。
如果您在GUI线程中意外地运行,则GUI将在单击按钮后立即死亡。所以我想我们可以排除这个可能性。
您描述的内容听起来更像是内存负载/性能问题。我强烈建议将Visualvm与您的应用程序连接起来,特别是要不断增加内存消耗。此外,使用visualvm中包含的分析器可能会提示需要消耗大量cpu或内存的东西。
发布于 2012-08-02 19:54:51
溶液增编:
在此应用程序的最终测试过程中,我更仔细地确定了GUI的明显来源。所谓GUI慢下来,我指的是复制2500个文件之间的区别.慢下来的问题需要将近20分钟才能完成.应用修复后,相同的文件需要不到1分钟的时间复制。
问题副本通过Worker处理。工作线程定期更新GUI。更新包括一个ProgressBar更新和一个文本框更新。
文本框更新似乎是问题的根源。我想要的是一个文本框PREPENDS --状态更新信息--比如“复制文件C:/hello.txt”--而不是附加(可在SWT中找到)。为了创建我所使用的人造代码(在一个单独的线程中):
textfeedback.setText(workerthreadinfo + "\n" + textfeedback.getText()) ;
这一小块代码似乎是慢下来的罪魁祸首--也许很容易看出原因。在每个文件副本上,复制整个文本框内容,然后将新信息加到文本框中。在复制了大约700个文件后,它开始陷入停滞(您可以明显地看到慢下来),并在之后继续恶化。
尽管我对此不满意,但修复方法是使用SWT TextBox append()方法。
https://stackoverflow.com/questions/10787081
复制相似问题