SwingWorker:CPU使用率100%!

时间:2012-01-15 10:38:58

标签: java swing user-interface swingworker

我的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()”方法不提供此信息

2 个答案:

答案 0 :(得分:1)

您的CPU自然而然地高达100%,因为您在while (!task.isDone());中闲置 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()方法。

答案 1 :(得分:1)

不回答......

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

1)实现Executor & SwingWorker,注意关于take error from Future

2)通过将方法包装到Runnable#Thread,通知GUI的输出必须包含在invokeLater中,

3)创建一些ThreadFactory or implements Executor,在invokeLater需要的某些情况下,GUI的通知输出必须包含invokeAndWait

4)您可以模拟/比较性能问题Christmas Tree Applications