我有一个小问题,现在我必须处理一个小的 Java 项目。我正在尝试从 Button 事件处理程序运行一些线程;那么最后一个线程必须更新 UI 上的 TextArea。线程正在做计算工作。最重要的部分是让 UI 工作正常——我不想卡住 UI,当然我想从其他线程之一(不是 ui 的线程)定期更新 UI 的 TextArea。所以这是我的代码的一部分:
在 Button 的事件处理程序中,我启动了这 4 个线程:
Thread generate = new CombinaMaker();
generate.run();
Thread forward = new TranslateForward();
forward.run();
Thread backward = new TranslateBackward();
backward.run();
Thread refresh = new Refresher();
refresh.run();
我希望线程同时工作。 Refresher 线程必须定期更新 UI TextArea 组件。
下面是我如何从 Refresher 线程更新 UI:
public static void updateProgress()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
//HERE
//I have a loop that have to be looping at every 500 ms
}
}
}
我的问题是:我应该做这个链接吗?我需要简单有效。这个循环让我很难过,因为只要应用程序工作,它就必须循环。这可能是卡住 UI 的原因?我知道我在某个地方犯了很大的错误,但此刻我一个人找不到。也许你可以建议我一些简单的解决方案。最后一个想法 - 前 4 个线程:我想“同时”启动它们,而不卡住我的 UI。这种方式(从事件处理程序中像这样启动它们......)是正确的方式还是可能更好?非常感谢 friend 们!
附言。如果通过我的“刷新”线程刷新 UI 是一项艰巨的工作,我准备好进行折衷变体 - 通过他自己的线程(UI 线程)更新 UI。但在这种情况下,我可能必须使用某种“时间拍摄机制”——避免 UI 卡住。你在想什么?
最佳答案
主要问题是你的算法。而不是
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//HERE
//I have a loop that have to be looping at every 500 ms
}
}
你应该有
// HERE
// I have a loop that have to be looping at every 500 ms
// and when something must be updated in the GUI:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// update the GUI as fast as possible
}
});
即
while (true) {
Thread.sleep(500L);
String update = getUpdate();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(update);
}
});
}
传递给 SwingUtilities.invokeLater()
的可运行对象在事件调度线程中执行。它不得执行长时间运行的任务。无限循环是一项非常耗时的任务。
关于Java:如何启动一些异步操作并从其他线程更新用户界面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12923625/