SwingUtilities.invokeLater需要一个Runnable并运行它在美国东部时间? [英] SwingUtilities.invokeLater takes a Runnable and runs it on the EDT?

查看:136
本文介绍了SwingUtilities.invokeLater需要一个Runnable并运行它在美国东部时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑与 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 calls invokeLater 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆