java 解释下面的代码是做什么的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4908824/
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
Explain what the following code does?
提问by Deepak
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
Please tell me what does the above code does actually. I am looking for line by line explanation. especially the first line and tell me why do we use that and in what scenarios we have to use this.
请告诉我上面的代码实际上做了什么。我正在寻找逐行解释。尤其是第一行,告诉我为什么要使用它以及在什么情况下必须使用它。
回答by yankee
In this Example you see an anyonmous class that derives from Runnable. This anonymous class overrides the run method of the interface runnable. Then this anonymous class is instantiated and passed to the EventQueue.invokeLater method, which is a static method. This method appends the object into... well... the eventQueue. In the EvenQueue are many events, like keyboard events or mouse events or whatever. There is a Thread that continuesly polls data from this queue. Once that Thread reaches the anonymous class that was instantiated here, it will execute the run() method, which will instantiate an Object of class NewJFrame and set it to be visible.
在此示例中,您会看到一个从 Runnable 派生的任意类。这个匿名类覆盖了接口 runnable 的 run 方法。然后这个匿名类被实例化并传递给EventQueue.invokeLater方法,它是一个静态方法。此方法将对象附加到...好吧... eventQueue。EvenQueue 中有很多事件,比如键盘事件或鼠标事件等等。有一个线程不断地从这个队列中轮询数据。一旦该线程到达此处实例化的匿名类,它将执行 run() 方法,该方法将实例化 NewJFrame 类的对象并将其设置为可见。
The whole point of doing this this complicated is that the new JFrame().setVisible(true) part is not executed in the main thread, but in the event dispatching thread. In Swing you must execute all code that modifies the user interface in the event dispatching thread.
这样做的重点是 new JFrame().setVisible(true) 部分不是在主线程中执行的,而是在事件调度线程中执行的。在 Swing 中,您必须在事件调度线程中执行所有修改用户界面的代码。
回答by smwikipedia
Single-Thread-Model and EDT
单线程模型和 EDT
Most modern UI libraries adopt the single-thread-model
. That means, all the manipulation upon UI components MUST be done on the same single thread. Why? That's because allowing UI components being updated from multiple threads will lead to chaos since most Swing object methods are not "thread safe". For simplicity, efficiency and robustness, single-thread-model is adopted.
大多数现代 UI 库都采用single-thread-model
. 这意味着,对 UI 组件的所有操作都必须在同一个线程上完成。为什么?这是因为允许从多个线程更新 UI 组件会导致混乱,因为大多数 Swing 对象方法都不是“线程安全的”。为了简单、高效和健壮,采用单线程模型。
In Swing, the very thread that serve the single-thread-model
is called the Event Dispatching Thread, i.e. EDT. It is not provided by Swing. It is provided by Abstract Window Toolkit, i.e. AWT.
在 Swing 中,服务于 的线程single-thread-model
称为Event Dispatching Thread,即 EDT。它不是由 Swing 提供的。它由Abstract Window Toolkit 提供,即 AWT。
Worker thread vs UI thread
工作线程与 UI 线程
A non-trivial GUI application usually has many threads. In modern GUI application, there can be many worker threads to do dirty work, but there's only oneUI thread (Swing calls it EDT) to update the GUI. Worker threads usually need to reflect their work progress in GUI, so they need to communicate with the UI thread about that. So how does this communication happen?
一个重要的 GUI 应用程序通常有许多线程。在现代 GUI 应用程序中,可以有许多工作线程来做脏活,但只有一个UI 线程(Swing 称之为 EDT)来更新 GUI。工作线程通常需要在 GUI 中反映它们的工作进度,因此它们需要与 UI 线程通信。那么这种沟通是如何发生的呢?
java.awt.EventQueue
java.awt.EventQueue
The communication happens through a message queue model. The java.awt.EventQueue
is the very class that provides a event queue globally. This global event queue serves as the communication channel to the EDT. EDT picks up messages from this EventQueue and update UI components accordingly. If some other part of your program wants to manipulate the UI, that part of code should call EventQueue.invokeLater()
or EventQueue.invokeAndWait()
to queue a message into EventQueue. EDT will process all the pending messages in the EventQueue and eventually get to the message.
通信通过消息队列模型进行。该java.awt.EventQueue
是非常类,提供了一个事件队列全球。此全局事件队列用作与 EDT 的通信通道。EDT 从此 EventQueue 中获取消息并相应地更新 UI 组件。如果程序的其他部分想要操作 UI,那部分代码应该调用EventQueue.invokeLater()
或EventQueue.invokeAndWait()
将消息排队到 EventQueue 中。EDT 将处理 EventQueue 中所有待处理的消息并最终获取到该消息。
the main thread
主线程
Your code snippet usually resides in the main()
thread, the main
thread can be viewed as some kind of a worker thread
here. Only that instead of updating the GUI by posting messages to EventQueue, it initiates the GUI. Anyway, initiation can be viewed as a kind of work, too.
您的代码片段通常驻留在main()
线程中,main
可以将线程视为某种 a worker thread
here。只是它不是通过将消息发布到 EventQueue 来更新 GUI,而是启动 GUI。不管怎样,启蒙也可以看作是一种工作。
After the GUI is initiated, the main thread will exits and the EDT will prevent the process from exiting.
GUI启动后,主线程会退出,EDT会阻止进程退出。
And another good explanation:
另一个很好的解释:
Java Event-Dispatching Thread explanation
Java Event-Dispatching Thread解释
An interesting article: Multi-threaded toolkit, a failed dream?
一篇有趣的文章: 多线程工具包,一个失败的梦想?
回答by kelloti
This is a block of code that is instructed to execute at a later time (sometimes called a deferred). The inner class (new Runnable() {...}
) is essentially allowing you to pass a block of code that will be run. The invokeLater
methodguarantees that the block of code will be run, but makes no guarantees of when. Sometimes it's not safe to have certain code run immediately, and its too verbose to do the multi-threading yourself. So Java provides this utility method to safely run the code. The code will be run very soon, but not until it's safe to do so.
这是一段被指示在稍后执行的代码块(有时称为deferred)。内部类 ( new Runnable() {...}
) 本质上允许您传递将要运行的代码块。该invokeLater
方法保证代码块将运行,但不保证何时运行。有时让某些代码立即运行是不安全的,而且自己进行多线程处理太冗长了。所以Java提供了这个实用方法来安全地运行代码。代码将很快运行,但要等到安全运行时才会运行。
回答by vidstige
The invokeLater
call will put the specified runnable on a queue to be processed later. That is, the code inside the run()
method will not have been run yet when the invokeLater
method call returns.
该invokeLater
调用会将指定的 runnable 放在队列中以供稍后处理。也就是说,run()
当invokeLater
方法调用返回时,方法内部的代码还没有运行。
There are two typical use-cases for this type of code.
这种类型的代码有两个典型的用例。
- The currently executing code is run in a background thread. Background threads cannot access most of the swing API. Read more herefor the reason for this. If the current thread is already the UI thread there is no reason and the call can safely be removed.
- The current block must be exited, ie the code reach the last brace. This may cause resources to be released and so on. This is not so common.
- 当前正在执行的代码在后台线程中运行。后台线程无法访问大部分的 Swing API。在这里阅读更多的原因。如果当前线程已经是 UI 线程,则没有任何理由并且可以安全地删除调用。
- 必须退出当前块,即代码到达最后一个大括号。这可能会导致资源被释放等。这并不常见。
An anonymous class is passed as parameter to the invokeLater
call. It is the same as this code.
匿名类作为参数传递给invokeLater
调用。它与此代码相同。
private void foo()
{
java.awt.EventQueue.invokeLater(new JFrameCreator());
}
private class JFrameCreator implements Runnable
{
public void run() {
new NewJFrame().setVisible(true);
}
}
回答by topgun_ivard
The invokeLater() method takes a Runnable object as its parameter. It sends that object to the event-dispatching thread, which executes the run() method. This is why it's always safe for the run() method to execute Swing code.
invokeLater() 方法将 Runnable 对象作为其参数。它将该对象发送到执行 run() 方法的事件调度线程。这就是为什么 run() 方法执行 Swing 代码总是安全的。
-IvarD
-IvarD