0

我有一个带有 gui 的简单 JAVA 程序,它只增加 int 变量并在 JLabel 中显示它的值。我通过在其中调用带有 Runnable 类的 EventQueue.invokeLater() 来创建新线程以正确(线程安全)更新 JLabel,而 run 方法只是这样做

EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            label.setText("" + number);
        }
    });

当我运行程序时,正如预期的那样,标签的数量开始从 1 快速增长到大约 5000,但随后开始放缓,我开始看到此类标签​​的更新,如 100255、173735、235678,并且它们之间的大停顿与阻塞的 GUI。但是,当我在不使用 EventQueue.invokeLater() 的情况下进行编译时,直接调用label.setText("" + number);一切正常且完美,我可以看到我的标签的每个数字如何变化得非常快。但是我当然意识到在这种情况下我的方法不是线程安全的。

有什么问题?在我看来,EventQueue 工作缓慢或什么的。

4

1 回答 1

3

可能,事件队列被阻塞了。当您将事件排队的速度比出队和操作的速度快时,您可能希望查看合并事件以删除冗余条目。

每次将事件添加到队列中时,都会查询现有事件以查看它们是否将新事件与自身合并。随着队列的备份,越来越多的事件必须如此查询,并且系统逐渐落后。这对鼠标事件很有用,但在像这样的简单(和人为)情况下,它可能是有害的。

话虽如此,我隐约记得 GUI 代码经过优化,不会尝试合并未覆盖适当方法的事件,因此您的问题可能只是一个简单的积压。

您可以创建一个自定义事件来设置组件上的文本,而不是直接调用setText,为它实现合并并使用它来代替,以便在任何给定时间只有最近的文本处于待处理状态。如果您这样做并且您想根据之前设置的内容来设置文本,那么最好保留该值并始终从中设置 GUI 小部件,而不是使用 调用 GUI 小部件的当前值getText。否则合并会困难得多。

于 2013-09-25T19:09:28.910 回答