Java SwingUtilities.invokeLater 有什么作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6567870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:48:04  来源:igfitidea点击:

What does SwingUtilities.invokeLater do?

javamultithreadingswingawtevent-dispatch-thread

提问by

What does SwingUtilities.invokeLaterdo? Is it just delaying the execution of a block of codes inside its runmethod? What is the difference between calling an action within the invokeLaterfunction or simply calling it at the end of the thread we want to be executed? Can anyone help me with what really does the invokeLaterfunction do?

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

采纳答案by Maurice Naftalin

As other answers have said, it executes your Runnableon the AWT event-dispatching thread. But why would you want to do that? Because the Swing data structures aren't thread-safe, so to provide programmers with an easily-achievable way of preventing concurrent access to them, the Swing designers laid down the rule that all code that accesses them must run on the same thread. That happens automatically for event-handling and display maintenance code, but if you've initiated a long-running action - on a new thread, of course - how can you signal its progress or completion? You have to modify a Swing control, and you have to do it from the event-dispatching thread. Hence invokeLater.

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

回答by MByD

It will run the piece of code on the AWT thread. Which lets you modify the GUI from other threads.

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

From Docs:

文档

Causes doRun.run() to be executed asynchronously on the AWT event dispatching thread. This will happen after all pending AWT events have been processed. This method should be used when an application thread needs to update the GUI.

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

回答by mKorbel

that's would be Comment, but looks like as longer as..., just basic stuff

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

1/ create own EDT for correct update to the GUI, f.e. if you are executed some code by using plain vanilla Thread, java.util.Timer, Executor.. more here

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

2/ helps with set Focusto the JComponentsiof there are some Listenersbecause if is there f.e. DocumentListenerthen you hard to set Focusto the desired JComponents

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

3/ delay code executions block and move that to the ends of EDT

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

回答by RalphChapin

As already noted, InvokeLater allows you to safely call methods in swing classes when you are not running on the EventQueue to begin with. However, you can simplify your code and your life by accessing other fields and classes onlyfrom the EventQueue. They can work with swing and each other without all the hassles of multi-threading. If you have started another thread, use InvokeLater to get back to the EventQueue as quickly as possible and minimize the number of fields that must be synchronized or otherwise guarded.

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

If you need to make the most of multiple cores you will have to reduce your use of the EventQueue, and you will have to pay a big price in complexity.

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

回答by gerardw

Note that you eventually get a call to your doRun.run( ) method for everytime you call invokeLater(doRun). So if you call it ten times before the event thread gets an opportunity to perform its processing, you are likely to then get ten successive calls to doRun.run( ).

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