SwingUtilities.invokeLater需要一个Runnable并运行它在美国东部时间? [英] SwingUtilities.invokeLater takes a Runnable and runs it on the EDT?
问题描述
我很困惑与 SwingUtilities.invokeLater
的签名。它需要一个的Runnable
对象。难道是交给事件指派线程此Runnable对象?我为什么不能直接调用 createAndShowGUI
在
(如果有可能)? EDT运行
法
我有阅读文章的对等如何的 EDT 和的的invokeLater 的工作,但我很困惑与的Runnable
对象传递。
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
createAndShowGUI();
}
});
如果我叫会发生什么 SwingUtilities.invokeLater
再次右键下方的电话吗?
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
createAndShowGUI();
}
});
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
doSomethingOnTopOfGUI();
}
});
什么是新的Runnable(){}?
新的Runnable(){
公共无效的run(){
createAndShowGUI();
}
};
这个声明匿名类和实例化的一个新的实例。它基本上是相同的:
类造物主实现Runnable {
公共无效的run(){
createAndShowGUI();
}
}新创();
Java的8 lambda表达式之前,匿名类是没有办法做到的一种功能性的节目。传递一个Runnable到的invokeLater
就像轻描淡写地说,美国东部时间可以执行以后每当它想要一个功能(通过调用运行
上它)。
什么用的invokeLater了Runnable办?
最初,它是所有创建一个事件把它包起来(一个的 InvocationEvent ),并把它在队列的末尾。
排队活动结束后,的invokeLater
通知EDT(其唤醒,如果它在等待)。该EDT自己的run方法是一个无限循环处理事件。它看起来是这样的(很转述):
公共无效的run(){
而(真){
EventQueue的EQ = getEventQueue(); 同步(当量){
而(eq.hasNextEvent()){
processOneEvent(eq.getNextEvent());
} 尝试{
eq.wait();
}赶上(InterruptedException的IE){}
}
}
}
当EDT获取到新的InvocationEvent,它会调用运行
上运行的,这就要求 createAndShowGUI
。
所以传递一个Runnable到的invokeLater
或 invokeAndWait
让你c您希望在美国东部时间运行的任何$ C $
如何尽快运行叫什么名字?
在大多数情况下,立即或几乎立即。该EDT是非常敏感。的的invokeLater的后来的部分仅仅是一个暗示我们说:
-
运行
异步执行。调用线程的invokeLater
可继续过去的呼叫处理事件之前。 - 其他事件可能得到优先处理。
运行同步调用
希望当然, invokeAndWait
的存在作为替代。 (虽然应该注意的是 invokeAndWait
也可能会导致当它们被新InvocationEvent之前排队等待处理其它事件。)
异步
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
的System.out.println(你好);
}
});
的System.out.println(世界);
这可以打印
你好
世界
和它可以打印
世界
你好
,因为调用线程可以或可以不之前继续(或者甚至同时)为该事件被处理。这取决于系统的线程调度
同步
SwingUtilities.invokeAndWait(新的Runnable(){
公共无效的run(){
的System.out.println(你好);
}
});
的System.out.println(世界);
这肯定会打印
你好
世界
由于调用线程等待运行
来完成它继续执行之前(除非抛出一个异常)。
invokeAndWait
使用等待和通知方式实现这一目标。监视器对象被创建并给予InvocationEvent。 invokeAndWait
要求等
发布事件和InvocationEvent来电之后 notifyAll的
运行后
完成了在EDT。等待和通知机制是一个道理 invokeAndWait
不能在EDT调用。该EDT没有办法阻止在一个事件的中间处理一个不同的。
在一个以上的事件进行排队,会发生什么?
在美国东部时间处理事件一次,他们的顺序进行排队,并根据它们的优先级。某些事件还可以得到合并(定期InvocationEvent不会)。大多数事件是正常的优先级。一个的paintEvent(像调用重绘
)通常是低优先级和某些系统事件是高优先级的。
在具体的例子,你已经给:
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
createAndShowGUI();
}
});
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
doSomethingElse();
}
});
由于他们是同一类型的事件和相同的优先级, doSomethingElse
活动将在 createAndShowGUI
活动就完成了。
同样,如果像这样做了:
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
SwingUtilities.invokeLater(Runnable的新(){
公共无效的run(){
的System.out.println(世界);
}
});
的System.out.println(你好);
}
});
这将打印
你好
世界
因为全球
的Runnable得到了你好
的Runnable完成之后运行。
I am confused with the signature of SwingUtilities.invokeLater
. It takes a Runnable
object. Is it this Runnable object that is handed over to the Event Dispatch Thread? Why can't I directly call createAndShowGUI
on the run
method of EDT
(if it is possible)?
I have read articles on SO on how the EDT and invokeLater work, but I am confused with the Runnable
object that is passed.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
And what would happen if I call SwingUtilities.invokeLater
again right below the call?
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
doSomethingOnTopOfGUI();
}
});
What is new Runnable() {}?
new Runnable() {
public void run() {
createAndShowGUI();
}
};
This declares an anonymous class and instantiates a new instance of it. It is basically equivalent to this:
class Creator implements Runnable {
public void run() {
createAndShowGUI();
}
}
new Creator();
Before Java 8 lambdas, an anonymous class is a way to do a kind of functional programming. Passing a Runnable to invokeLater
is like passing a function that the EDT can execute later whenever it wants (by calling run
on it).
What does invokeLater do with the Runnable?
Initially, all it does is create an event to wrap it (an InvocationEvent) and put it at the end of a queue.
After queuing the event, invokeLater
notifies the EDT (which wakes up if it was waiting). The EDT's own run method is an infinite loop that processes events. It looks something like this (very paraphrased):
public void run() {
while(true) {
EventQueue eq = getEventQueue();
synchronized(eq) {
while(eq.hasNextEvent()) {
processOneEvent(eq.getNextEvent());
}
try {
eq.wait();
} catch(InterruptedException ie) {}
}
}
}
When the EDT gets to the new InvocationEvent, it calls run
on the Runnable, which calls createAndShowGUI
.
So passing a Runnable to invokeLater
or invokeAndWait
lets you run any code you want on the EDT.
How soon is run called?
In most cases, immediately or almost immediately. The EDT is very responsive. The 'Later' part of 'invokeLater' is just a hint to us that:
run
is executed asynchronously. The thread that callsinvokeLater
may continue past the call before the event is processed.- Other events may be processed first.
Of course invokeAndWait
exists as an alternative if a synchronous call to run
is desired. (Though it should be noted that invokeAndWait
may also cause other events to be processed if they were queued before the new InvocationEvent.)
Asynchronous
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("hello");
}
});
System.out.println("world");
This may print
hello world
and it may print
world hello
because the calling thread may or may not continue before (or even while) the event is processed. It depends on the system's thread scheduler.
Synchronous
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.out.println("hello");
}
});
System.out.println("world");
This will definitely print
hello world
because the calling thread will wait for run
to complete before it continues (unless an exception is thrown).
invokeAndWait
uses a wait and notify scheme to achieve this. A monitor object is created and given to the InvocationEvent. invokeAndWait
calls wait
after posting the event and the InvocationEvent calls notifyAll
after run
completes on the EDT. The wait and notify scheme is a reason invokeAndWait
cannot be called on the EDT. The EDT does not have a way to stop in the middle of one event to process a different one.
What happens if more than one event is queued?
The EDT processes events one at a time, in the order they are queued and according to their priority. Some events can also get merged (a regular InvocationEvent will not). Most events are normal priority. A PaintEvent (like from calling repaint
) is typically low priority and certain system events are of higher priorities.
In the specific example you've given:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
doSomethingElse();
}
});
Since they are the same kind of event and the same priority, the doSomethingElse
event will be processed after the createAndShowGUI
event is done.
Similarly, if something like this were done:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("world");
}
});
System.out.println("hello");
}
});
That will print
hello world
because the world
Runnable gets run after the hello
Runnable completes.
这篇关于SwingUtilities.invokeLater需要一个Runnable并运行它在美国东部时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!