SwingWorker:CPU 使用率 100%!

发布于 2024-12-26 17:33:34 字数 905 浏览 0 评论 0原文

我的 Swing 应用程序有一个表,当从外部源获取某些数据时会填充该表。为了显示数据,我使用 SwingWorker 线程,该线程是从应该以这种方式获取数据的线程调用的:

 // SwingWorker Thread
 private class DisplayRowsTask extends SwingWorker<Void, Object[]> {

    private Vector<String[]> _data;

    @Override
    protected Void doInBackground() {
        while (_continue && !hasError()) {
            // some logic to fetch and place data in _data
            // data adjustment
            for (String[] row : _data) publish (row);
            _data = new Vector<String[]>();
        }
        return null;
    }

    @Override
    protected void process(List<Object[]> rows) {
        for (Object[] row : rows) ((DefaultTableModel)_table.getModel()).addRow(row);
    }
}

显示的结果是正确的,除了 CPU 使用率为 100%(甚至超过!)之外,一切都工作正常,尤其是在频繁获取大量数据的情况。我如何限制这种使用?

另一个问题可能不完全相关:我如何知道数据是否显示在表中?方法“SwingWorker.isDone()”不提供此信息

My Swing application has a table which is populated when some data are fetched from an external source. To display data I'm using SwingWorker thread which is called from the thread that is supposed to fetch the data in this way:

 // SwingWorker Thread
 private class DisplayRowsTask extends SwingWorker<Void, Object[]> {

    private Vector<String[]> _data;

    @Override
    protected Void doInBackground() {
        while (_continue && !hasError()) {
            // some logic to fetch and place data in _data
            // data adjustment
            for (String[] row : _data) publish (row);
            _data = new Vector<String[]>();
        }
        return null;
    }

    @Override
    protected void process(List<Object[]> rows) {
        for (Object[] row : rows) ((DefaultTableModel)_table.getModel()).addRow(row);
    }
}

The results displayed are correct and everything works fine apart that the CPU usage is 100% (and over!) especially in the situation where a lot of data are fetched frequently. How can I limit this usage?

Another question maybe not fully related: how can I know if the data are been displayed in the table? The method "SwingWorker.isDone()" doesn't give this information

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黄昏下泛黄的笔记 2025-01-02 17:33:34

您的 CPU 自然会达到 100%,因为您在空闲循环 while (!task.isDone()); in run()SwingWorker 通过调用 execute(); 异步执行,因此您不必在 Thread 中执行它。无论如何,您都不应该在 Swing 中使用ThreadSwingWorker 完成这项工作。它有钩子方法来在代码完成时调用它。
如果您有许多任务要执行,请在 SwingWorker 本身中实现它们。

像这样:

   @Override
    protected Void doInBackground() {
      while (_continue && !hasError()) {
        // do some adjustments around _data
        for (String[] row : _data) publish (row);
       }
       return null;
    }

对于另一个问题:
我认为 addRow(...) 会触发事件。您的表应该收到此事件并使组件无效。如果您想在 SwingWorker 完成后执行代码,请重写 done() 方法。

Your CPU is going up to 100% naturally, because you're idly looping while (!task.isDone()); in run(). SwingWorker is executed asynchronously by calling execute(); so you don't have to execute it in a Thread. You shouldn't use Thread anyway in Swing. The SwingWorker does the job. It has hook methods to invoke code when it's finished.
If you have many tasks to execute implement them in the SwingWorker itself.

Something like this:

   @Override
    protected Void doInBackground() {
      while (_continue && !hasError()) {
        // do some adjustments around _data
        for (String[] row : _data) publish (row);
       }
       return null;
    }

To another question:
I think addRow(...) fires event. Your table should get this event and invalidate component. If you want to execute code after SwingWorker is done, then override done() method.

朦胧时间 2025-01-02 17:33:34

不回答....

不知道你尝试了什么,因为我无法通过实现 Essential Java 正确,如果您是 IDE 用户,那么您可以使用内置的 JProfiler 分析您的代码,然后您可以看到当前 JVM 中的所有重要事件,但基本上您有三种选择

1) 实现 Executor & SwingWorker,请注意来自 Future 的错误

2) 将你的方法包装到 Runnable#Thread,注意 GUI 的输出必须包装到 invokeLater 中,

3) 创建一些 ThreadFactory 或实现 Executor,注意 GUI 的输出必须包装到invokeLater 在某些情况下需要 invokeAndWait

4) 您可以模拟/比较性能问题圣诞树应用

not answer ....

not idea what did you tried because I not able to generating 100% CPU usage by implements Essential Java correctly, if you are IDE user then you can profile your code with built-in JProfiler, then there you can see all important events from current JVM, however basically you have three choises

1) implements Executor & SwingWorker, notice about take error from Future

2) by wrapping your methods to the Runnable#Thread, notice output to the GUI must be wraped into invokeLater,

3) create some ThreadFactory or implements Executor, notice output to the GUI must be wraped into invokeLater in some cases required into invokeAndWait

4) you can simulating/compare with performace issues Christmas Tree Applications

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文