java - SwingWorker 在方法 LockSupport.park() 中等待很长时间

标签 java swing swingworker

我在 Windows 10 64 位和 8 GB RAM 上使用 JDK 1.8。 我有一个 Swing 应用程序。 在应用程序中,我查询 DB2 数据库。 该查询返回数据库表名称和每个表的查询条件的列表。 这些表存在于单独的 SQL Server Express 数据库中。 我的 Swing 应用程序为每个 SQL Server Express 数据库表创建一个单独的 JComboBox,并使用收到的条件查询该表,并使用以下内容填充 JComboBox 模型:查询结果。 我循环遍历 DB2 查询的结果,并为每一行创建一个新的 JComboBox 并启动一个新的 SwingWorker 来查询 SQL Server Express 数据库。 最初,我的应用程序在 Windows 7 上使用 JDK 1.5 运行。 当然,SwingWorker 并不是 1.5 版本中 JDK 的一部分,因此我使用了第三方实现。 原始版本工作正常,但是在 Windows 10 上迁移到 JDK 1.8 后,完成所有这些初始化需要更多时间。 使用 VisualVM,时间增加是由于 SwingWorker 线程在 LockSupport 类的 park() 方法中等待。 我测量了执行该过程中每个步骤所需的时间,其中大多数需要百分之几秒才能完成,所有步骤的总时间不超过三秒。 我尝试在 JDK 1.8 版本中使用 JDK 1.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 屏幕截图:

VisualVM Screen Capture

最佳答案

可以看到在LinkedBlockingQueue.take()上被阻塞了,这意味着队列是空的,所以正在等待。这是完全正常且正确的。

你的问题出在其他地方。

现在你说你已经测量了时间,总时间约为 3 秒,但你暗示它实际上比这慢。我假设你的意思是需要超过 3 秒才能获得响应式 GUI。在这种情况下,听起来您似乎并未实际测量所有步数。例如,如果您要创建一个新的 Connection 对象而不是从池中获取一个对象,那么速度会非常慢,但它可能不会轻易显示在 VisualVM 中,除非您知道如何查找它。

最后,您可能会遇到线程争用问题,这些问题会通过诸如 LockSupport.park() 之类的内容出现,但了解它的用途很重要。在您的示例中,您有一个没有工作要做的工作线程,因此它正在 hibernate 。例如,这与死锁完全不同,死锁会显示为两个停放的线程(等待彼此的锁)。

那为什么之前可以用呢?也许它的工作是偶然的,而不是有意为之。也许 Java 版本无关紧要,您更改了其他内容。

关于java - SwingWorker 在方法 LockSupport.park() 中等待很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58569428/

相关文章:

java - 将 String 转换为 BigDecimal,始终保留两位小数

java - 如何将文本字段添加到 java swing 中按钮的 Action 监听器?我也有关于字符串的疑问

java - 使用图形在图像上进行文本换行?

java - 将用于将 Assets 文件复制到 Android 中的缓存文件夹的 Java 代码转换为 Kotlin 的最佳实践

java - 我可以用一个全新的项目覆盖 Git 存储库吗?

java - 静态类可以在java中有多个值吗(android java中的混淆示例)

java - 删除 TitledBorder 周围的间距

java - 使用 SwingWorker 可运行对象从 ExecutorService 获取正确类型的 Future

java - 允许哪些线程调用 SwingWorker#publish?

java - SwingWorker(不工作),循环在第一次迭代后结束