Java:如何启动一些异步操作并从其他线程更新用户界面?

标签 java multithreading user-interface refresh freeze

我有一个小问题,现在我必须处理一个小的 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/

相关文章:

java - 如何将 x509 证书和 key 转换为 pkcs12 文件

JavaFX 使用线程更快地动态填充 GridPane

java - 让 Java 应用程序在 Windows 上看起来是原生的 - 如何?

java - 在 Android 中动态创建/删除按钮

java - Java 中通知和等待的顺序

python - 修改默认 Ttk Clam 小部件颜色

java - 获取目录?

java - 实现 JFrame 时线程 "main"java.lang.NullPointerException 中出现异常

java - 如何制作数组的副本,以便副本中的任何更改都不会影响原始数组?

java - 如何在 Java 中完全停止线程?