检查线程是否需要 EDT?
我有一个用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
即使您在 EDT 上,稍后调用也可以,但是它肯定会改变事件的时间,因此您必须确保在 EDT 上时不依赖于此处的代码顺序。话虽这么说,避免忘记 else 的一个简单方法是将调用包装在实用方法中:
这样您就永远不会忘记
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:
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.我相信对于您的特定用例,检查 isEventDispatchThread() 是不必要的。直接调用
invokeLater()
不会创建新线程,因此不会出现性能损失。I believe for your particular use case, checking
isEventDispatchThread()
is unnecessary. Directly callinginvokeLater()
will not create a new thread, so this occurs no performance penalty.代码确实应该知道它是否在 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.简单地说,如果您的代码中有一个由 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.