SwingUtilities.invokeLater
做什么?它只是推迟在run
方法中执行一段代码吗?在invokeLater
函数中调用一个动作或者只是在我们想要执行的线程的末尾调用它有什么区别?任何人都可以帮助我了解invokeLater
函数的真正功能吗?
答案 0 :(得分:26)
正如其他答案所说,它在AWT事件派发线程上执行Runnable
。但是你为什么要那样做呢?由于Swing数据结构不是线程安全的,因此为程序员提供了一种易于实现的方法来阻止对它们的并发访问,Swing设计者规定了访问它们的所有代码必须在同一个线程上运行的规则。这会自动发生在事件处理和显示维护代码中,但是如果你已经启动了一个长时间运行的操作 - 当然是在一个新线程上 - 你怎么能指示它的进度或完成?您必须修改Swing控件,并且必须从事件派发线程执行此操作。因此invokeLater
。
答案 1 :(得分:9)
它将在AWT线程上运行该段代码。这使您可以从其他线程修改GUI。
来自Docs:
导致执行doRun.run() 在AWT事件上异步 调度线程。这将发生 在所有未决的AWT事件发生之后 处理。应该使用这种方法 当应用程序线程需要时 更新GUI。
答案 2 :(得分:2)
那将是评论,但看起来像......,只是基本的东西
1 /创建自己的EDT以正确更新GUI,例如。如果你使用简单的香草Thread,java.util.Timer,Executor执行了一些代码..更多here
2 /帮助设置Focus到JComponents iof有一些Listeners因为如果有f.e. DocumentListener然后您很难将Focus
设置为所需的JComponents
3 /延迟代码执行阻止并将其移至EDT的末尾
答案 3 :(得分:2)
如前所述,InvokeLater允许您在未在EventQueue上运行时安全地调用swing类中的方法。但是,您可以通过从EventQueue访问仅的其他字段和类来简化代码和生活。他们可以在没有多线程麻烦的情况下使用swing和彼此。如果您已启动另一个线程,请使用InvokeLater尽快返回EventQueue,并尽量减少必须同步或以其他方式保护的字段数。
如果您需要充分利用多个内核,则必须减少对EventQueue的使用,并且必须付出相当大的复杂代价。
答案 4 :(得分:1)
请注意,在调用invokeLater(doRun)的每个时间内,最终都会调用doRun.run()方法。因此,如果在事件线程获得执行其处理的机会之前调用它十次,那么您可能会连续十次调用doRun.run()。