检查线程是否需要 EDT?

发布于 2024-08-29 21:23:21 字数 607 浏览 7 评论 0原文

我有一个用 Swing 实现的 UI。一个组件执行一些可能需要一些时间的工作,因此我使用 SwingUtilities.invokeLater。然而,我正在阅读一些旧代码,并在 ActionListener 中发现了这一点:

if (!SwingUtilities.isEventDispatchThread()) {
    SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             // code X
         }
    });
} else {
   // code X
}

我认为这是有道理的,因为它将 code X 与 EDT 分开。然而,我发现它很容易出错,因为我已经使用过它几次了,而且两次我都忘记了 else 部分。

问题是:SwingUtilities.isEventDispatchThread() 检查是否必要?或者我可以假设我不在 EDT 中并且始终使用invokeLater吗?

多谢。

I have an UI implemented with Swing. One component does some work that may take some time, so I use SwingUtilities.invokeLater. However, I was reading some old code and found this in an ActionListener:

if (!SwingUtilities.isEventDispatchThread()) {
    SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             // code X
         }
    });
} else {
   // code X
}

I thought that it made sense since it separates code X from the EDT. However, I found it error-prone since I have used it a couple of times and both times I forgot the else part.

The question is: is the SwingUtilities.isEventDispatchThread() checking necessary? Or could I assume that I am not in the EDT and always use invokeLater?

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

想你的星星会说话 2024-09-05 21:23:21

即使您在 EDT 上,稍后调用也可以,但是它肯定会改变事件的时间,因此您必须确保在 EDT 上时不依赖于此处的代码顺序。话虽这么说,避免忘记 else 的一个简单方法是将调用包装在实用方法中:

public static void invokeInDispatchThreadIfNeeded(Runnable runnable) {
    if (EventQueue.isDispatchThread()) {
        runnable.run();
    } else {
        SwingUtilities.invokeLater(runnable);
    }
}

这样您就永远不会忘记 else

另外,一般来说,在您的 idom 中重复 code x 是一个非常糟糕的主意,因为您稍后可能会发现您必须修复或改进该代码,并且您只会在一个地方执行此操作,从而留下错误在另一个。

Invoking later is fine even if you are on the EDT, however it certainly changes the timing of events, so you have to be sure that you were not dependent on the sequence of the code here when you were on the EDT. That being said, a simple way to avoid forgetting the else is to wrap the call in a utility method:

public static void invokeInDispatchThreadIfNeeded(Runnable runnable) {
    if (EventQueue.isDispatchThread()) {
        runnable.run();
    } else {
        SwingUtilities.invokeLater(runnable);
    }
}

That way you never forget the else.

Also, in general in your idom repeating code x is a very bad idea, as you may find later that you have to fix or improve that code and you will only do it in one place, leaving a bug in the other.

花心好男孩 2024-09-05 21:23:21

我相信对于您的特定用例,检查 isEventDispatchThread() 是不必要的。直接调用 invokeLater() 不会创建新线程,因此不会出现性能损失。

I believe for your particular use case, checking isEventDispatchThread() is unnecessary. Directly calling invokeLater() will not create a new thread, so this occurs no performance penalty.

拥抱我好吗 2024-09-05 21:23:21

代码确实应该知道它是否在 EDT 上(如果相关的话)。因此 java.awt.EventQueue.isDispatchThread 应该留给断言。

The code really ought to know if it is on the EDT or not (if that is relevant). So java.awt.EventQueue.isDispatchThread should be left to assertions.

挖个坑埋了你 2024-09-05 21:23:21

简单地说,如果您的代码中有一个由 EDT 启动的线程(A),并且在该线程(A)中您有另一个必须修改 GUI 的线程(B),在这种情况下,您必须在线程(B)上使用 invokeLater )。但是,如果 GUI 的修改是由第一个线程 (A) 完成的,则无需使用 invokeLater。

Simply if you have on your code a thread(A)launch by the EDT, and in that thread(A) you have another thread(B) which have to modify your GUI, in that case you have to use invokeLater on thread(B). However, if the modification of your GUI is doing by first thread(A) it's not necessary to use invokeLater.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文