SwingUtilities.invokeLater 做啥? [复制]

Posted

技术标签:

【中文标题】SwingUtilities.invokeLater 做啥? [复制]【英文标题】:What does SwingUtilities.invokeLater do? [duplicate]SwingUtilities.invokeLater 做什么? [复制] 【发布时间】:2011-09-27 21:55:45 【问题描述】:

SwingUtilities.invokeLater 是做什么的?它只是延迟其run 方法内的代码块的执行吗?在invokeLater 函数中调用一个动作或在我们想要执行的线程结束时简单地调用它有什么区别?任何人都可以帮助我了解invokeLater 函数的真正作用吗?

【问题讨论】:

参见***.com/questions/5780936/… 了解背景(相关背景,但不重复)。 【参考方案1】:

正如其他答案所说,它在 AWT 事件调度线程上执行您的 Runnable。但是你为什么要这样做呢?因为 Swing 数据结构不是线程安全的,所以为了向程序员提供一种易于实现的防止并发访问它们的方法,Swing 设计者制定了规则,即所有访问它们的代码都必须在同一个线程上运行。对于事件处理和显示维护代码,这会自动发生,但是如果您已经启动了一个长时间运行的操作 - 当然是在一个新线程上 - 您如何表示它的进度或完成?您必须修改 Swing 控件,并且必须从事件分派线程中进行。因此invokeLater

【讨论】:

哦!所以这就是你可以在java中做异步单线程的方法!奇怪的是它必须与“Windowing”工具包捆绑在一起,但似乎有点不合适。 @Dmitry 这是一种有趣的看待方式。 Java 不为单线程提供语言级别的支持(有任何语言吗?)。因此,需要它的框架必须提供支持它的功能,并为客户端程序员正确使用它制定规则。这不是“Java 的实现方式”,而是一种用 Java 实现的方式。【参考方案2】:

它将在 AWT 线程上运行这段代码。这使您可以从其他线程修改 GUI。

来自Docs:

导致 doRun.run() 被执行 在 AWT 事件上异步 调度线程。这会发生 在所有未决的 AWT 事件已被 处理。应该使用这个方法 当应用程序线程需要 更新 GUI。

【讨论】:

【参考方案3】:

如前所述,InvokeLater 允许您在开始时不在 EventQueue 上运行时安全地调用 Swing 类中的方法。但是,您可以通过从 EventQueue 访问其他字段和类来简化您的代码和您的生活。他们可以与 swing 和彼此一起工作,而无需多线程的所有麻烦。如果您已启动另一个线程,请使用 InvokeLater 尽快返回 EventQueue,并尽量减少必须同步或以其他方式保护的字段数量。

如果您需要充分利用多个内核,您将不得不减少对 EventQueue 的使用,并且您将不得不为复杂性付出巨大的代价。

【讨论】:

【参考方案4】:

那应该是评论,但看起来和...一样长,只是基本的东西

1/ 创建自己的 EDT 以正确更新 GUI,f.e.如果您使用普通的香草Thread,java.util.Timer,Executor .. 执行一些代码。更多here

2/ 帮助将Focus 设置为JComponents iof 有一些Listeners 因为如果有f.e. DocumentListener 那么你很难将 Focus 设置为所需的 JComponents

3/ 延迟代码执行阻塞并将其移动到 EDT 的末尾

【讨论】:

【参考方案5】:

请注意,您最终会在每次调用invokeLater(doRun) 时调用doRun.run() 方法。因此,如果您在事件线程有机会执行其处理之前调用它十次,那么您很可能会连续调用十次 doRun.run()。

【讨论】:

以上是关于SwingUtilities.invokeLater 做啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章