我在Windows 10 64位上使用JDK1.8,内存为8GB.我有个Swing申请。在应用程序中,我查询DB2数据库。查询返回每个表的数据库表名称和查询条件的列表。这些表存在于单独的数据库中。我的Swing应用程序为每个Server数据库表创建一个单独的JComboBox,并使用接收到的条件查询该表,并使用查询结果填充JComboBox模型。我循环遍历DB2查询的结果,并为每一行创建一个新的JComboBox并启动一个新的SwingWorker来查询Server数据库。最初,我的应用程序是在Windows7上使用JDK1.5运行的。当然,在版本1.5中,SwingWorker不是JDK的一部分,所以我使用了第三方实现。原始版本运行良好,但是在Windows 10上迁移到JDK1.8之后,所有这些初始化都需要更多的时间才能完成。使用VisualVM,时间的增加是由于SwingWorker线程在类LockSupport的方法park()中等待。我测量了在这个过程中执行每一步所需的时间,其中大多数都花了几百秒来完成,所有步骤的总时间都不超过3秒。我尝试在JDK1.8版本中使用我的JDK1.5应用程序中的SwingWorker实现,但是所用的时间并没有改变。如何才能发现导致某些SwingWorker线程在park()方法中花费大约6秒的原因?或者,我如何改变我的设计以避免这个问题?
部分伪码..。
JPanel panel = new JPanel();
Connection db2Conn = // Connect to DB2
Statement s = db2Conn.createStatement();
ResultSet rs = s.executeQuery("SQL query");
while (rs.next()) {
new ListTask(panel, /* data from 'rs' */).execute();
}
class ListTask extends SwingWorker<Void, Void> {
// JComboBox will be added to this. See method 'done()'
private JPanel panel;
// Name of table in database.
private String tableName;
// Criteria for querying 'tableName'.
private List<String> criteria;
// Results of query.
private Object[] results;
public ListTask(JPanel aPanel, String table, List<String> where) {
panel = aPanel;
tableName = table;
criteria = where;
}
protected void doInBackground() {
// Populate "results"
return null;
}
protected void done() {
JComboBox<Object> combo = new JComboBox(results);
panel.add(combo);
}
}VisualVM屏幕截图:

发布于 2019-10-26 09:45:14
您可以看到它在LinkedBlockingQueue.take()上被阻塞,这意味着队列是空的,所以它在等待。这是完全正常和正确的。
你的问题在别的地方。
现在你说你已经测量了时间,总时间大约是3秒,但是你暗示它实际上比这个慢。我想您的意思是,获得响应性GUI需要超过3秒。在这种情况下,听起来似乎还没有真正度量过所有的步骤。例如,如果您正在创建一个新的Connection对象,而不是从池中获取一个对象,这很慢,但是除非您知道如何查找,否则它可能不会很容易地在VisualVM中显示。
最后,您可能会遇到类似LockSupport.park()之类的线程争用问题,但重要的是要了解它的用途。在您的示例中,您有一个没有工作可做的工作线程,因此它处于休眠状态。例如,它与死锁完全不同,死锁将显示为两个已停放的线程(等待对方的锁)。
那为什么以前起作用了?也许它是偶然的,而不是故意的。也许Java版本是不相关的,而且您改变了其他一些东西。
https://stackoverflow.com/questions/58569428
复制相似问题