SwingUtilities.invokeLater是做什么的?

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

正如其他答案所述,它在AWT事件分派线程上执行您的Runnable 。 但是,你为什么要这样做呢? 因为Swing的数据结构不是线程安全的,所以为了给程序员提供一个简单的方法来阻止并发访问它们,Swingdevise者规定了访问它们的所有代码都必须在同一个线程上运行的规则。 这会自动发生在事件处理和显示维护代码上,但是如果你已经启动了一个长时间的操作 – 当然是在一个新的线程上,你怎么能指出它的进度或完成? 你必须修改一个Swing控件,你必须从事件派发线程中完成。 因此invokeLater

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

从文档 :

导致doRun.run()在AWT事件派发线程上asynchronous执行。 所有待处理的AWT事件处理完成后,都会发生这种情况。 应用程序线程需要更新GUI时应使用此方法。

这将是评论,但看起来像… …更长,只是基本的东西

1 /创build自己的EDT正确更新到GUI,如果你是通过使用普通的香草线程 , java.util.Timer , Executor执行一些代码。

2 /帮助设置焦点到JComponents iof有一些Listeners,因为如果有的话DocumentListener然后你很难设置Focus到所需的JComponents

3 /延迟代码执行阻止并移动到EDT的结尾

如前所述,InvokeLater允许您在没有运行EventQueue的情况下安全地调用swing类中的方法。 但是,您可以通过仅从 EventQueue访问其他字段和类来简化代码和生活。 他们可以在摆动和彼此之间工作,而不用担心multithreading的麻烦。 如果您启动了另一个线程,则尽可能快地使用InvokeLater返回EventQueue,并尽量减less必须同步或保护的字段数。

如果您需要充分利用多个内核,您将不得不减lessEventQueue的使用,而且您将不得不付出巨大的代价。

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