首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:如何启动一些异步操作并从其他线程更新ui?

Java:如何启动一些异步操作并从其他线程更新ui?
EN

Stack Overflow用户
提问于 2012-10-17 05:22:36
回答 4查看 1.2K关注 0票数 1

我有一个小问题,现在我必须在一个小的Java项目上工作。我尝试从按钮事件处理程序中运行几个线程;然后最后一个线程必须更新UI上的TextArea。线程正在做计算的工作。最重要的部分是让UI正常工作-我不想冻结UI,当然我想定期从其他线程(而不是ui的线程)更新ui的TextArea。下面是我的代码的一部分:

在Button的事件处理程序中,我启动了这4个线程:

代码语言:javascript
复制
Thread generate = new CombinaMaker();
generate.run();

Thread forward = new TranslateForward();
forward.run();

Thread backward = new TranslateBackward();
backward.run();

Thread refresh = new Refresher();
refresh.run();

我希望线程同时工作。刷新线程必须定期更新UI TextArea组件。

因此,下面是我如何从刷新线程更新UI:

代码语言:javascript
复制
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。是这样的吗(从事件处理程序中像这样启动它们...)正确的还是可能有更好的?非常感谢朋友们!

PS。如果通过我的“刷新”线程刷新UI是一项艰巨的工作,我已经准备好了一个折衷的变体--通过他自己的线程(UI线程)来更新UI。但在这种情况下,我可能必须使用一些“时间拍摄机制”--避免UI冻结。你在想什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-17 05:38:34

主要的问题是你的算法。而不是

代码语言:javascript
复制
SwingUtilities.invokeLater(new Runnable() {   
    public void run() {
        //HERE
        //I have a loop that have to be looping at every 500 ms
    }
}

你应该有

代码语言:javascript
复制
// 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
    }
});

代码语言:javascript
复制
while (true) {
    Thread.sleep(500L);
    String update = getUpdate();
    SwingUtilities.invokeLater(new Runnable() {   
        public void run() {
            textArea.append(update);
        }
    });
}

传递给SwingUtilities.invokeLater()的runnable在事件分派线程中执行。它不能执行长时间运行的任务。无休止的循环是一项非常漫长的任务。

票数 3
EN

Stack Overflow用户

发布于 2012-10-17 05:38:11

您不希望在传递给invokeAndDoLater的runnable中进行循环。请看下面的示例:http://www.javamex.com/tutorials/threads/invokelater.shtml

票数 2
EN

Stack Overflow用户

发布于 2012-10-17 05:32:10

SwingUtilities.invokeLater未设计为调用长时间运行的线程。您的问题的一个解决方案可能是this one

您还可以尝试颠倒循环和SwingUtilities.invokeLater调用的嵌套,但这样做的可行性取决于代码的其余部分

代码语言:javascript
复制
do {
    // Sleep and other stuff
    SwingUtilities.invokeLater(new Runnable() {
        public void run()  {
        // Update UI
        }
    });
} while(...);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12923625

复制
相关文章

相似问题

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