SwingWorker:CPU 使用率 100%!
我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的 CPU 自然会达到 100%,因为您在空闲循环
while (!task.isDone());
inrun()
。SwingWorker
通过调用execute();
异步执行,因此您不必在Thread
中执行它。无论如何,您都不应该在 Swing 中使用Thread
。SwingWorker
完成这项工作。它有钩子方法来在代码完成时调用它。如果您有许多任务要执行,请在
SwingWorker
本身中实现它们。像这样:
对于另一个问题:
我认为
addRow(...)
会触发事件。您的表应该收到此事件并使组件无效。如果您想在SwingWorker
完成后执行代码,请重写done()
方法。Your CPU is going up to 100% naturally, because you're idly looping
while (!task.isDone());
inrun()
.SwingWorker
is executed asynchronously by callingexecute();
so you don't have to execute it in aThread
. You shouldn't useThread
anyway in Swing. TheSwingWorker
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:
To another question:
I think
addRow(...)
fires event. Your table should get this event and invalidate component. If you want to execute code afterSwingWorker
is done, then overridedone()
method.不回答....
不知道你尝试了什么,因为我无法通过实现 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 choises1) 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 intoinvokeAndWait
4) you can simulating/compare with performace issues Christmas Tree Applications