49

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

4

5 回答 5

35

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

于 2011-07-04T06:40:07.920 回答
10

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

文档

导致 doRun.run() 在 AWT 事件分派线程上异步执行。这将在处理完所有待处理的 AWT 事件后发生。当应用程序线程需要更新 GUI 时,应使用此方法。

于 2011-07-04T06:11:12.130 回答
3

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

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

于 2011-07-05T03:25:36.800 回答
2

那将是评论,但看起来像...一样长,只是基本的东西

1/ 创建自己的 EDT 以正确更新 GUI,如果您使用普通的 vanilla Threadjava.util.TimerExecutor执行一些代码.. 更多在这里

2/ 帮助将焦点设置为JComponents iof 有一些监听器,因为如果有 fe DocumentListener那么你很难设置Focus为所需的JComponents

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

于 2011-07-04T06:58:02.323 回答
1

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

于 2012-12-03T15:32:03.560 回答