java swing invokelater_java – SwingUtilities.invokeLater采用Runnable并在...

什么是新的Runnable(){}?

new Runnable() {

public void run() {

createAndShowGUI();

}

};

这声明了一个匿名类并实例化它的新实例.它基本上相当于:

class Creator implements Runnable {

public void run() {

createAndShowGUI();

}

}

new Creator();

在Java 8 lambdas之前,匿名类是一种进行函数式编程的方法.将Runnable传递给invokeLater就像传递一个EDT可以随时执行的函数(通过调用run on).

invokeLater对Runnable做了什么?

最初,它所做的只是创建一个事件来包装它(一个InvocationEvent)并将它放在队列的末尾.

排队事件后,invokeLater会通知EDT(如果等待则会唤醒它). EDT自己的run方法是一个处理事件的无限循环.它看起来像这样(非常复述):

public void run() {

while(true) {

EventQueue eq = getEventQueue();

synchronized(eq) {

while(eq.hasNextEvent()) {

processOneEvent(eq.getNextEvent());

}

try {

eq.wait();

} catch(InterruptedException ie) {}

}

}

}

当EDT到达新的InvocationEvent时,它调用Runnable上的runnable,它调用createAndShowGUI.

因此,将Runnable传递给invokeLater或invokeAndWait可以让您在EDT上运行任何所需的代码.

跑多久叫?

在大多数情况下,立即或几乎立即.美国东部时间非常敏感. ‘invokeLater’的’Later’部分只是暗示我们:

> run是异步执行的.在处理事件之前,调用invokeLater的线程可能会继续通过调用.

>可以先处理其他事件.

当然,如果需要同步调用run,则invokeAndWait作为替代方案存在. (虽然应该注意,如果invokeAndWait在新的InvocationEvent之前排队,它们也可能导致处理其他事件.)

异步

SwingUtilities.invokeLater(new Runnable() {

public void run() {

System.out.println("hello");

}

});

System.out.println("world");

这可能会打印

hello

world

它可能会打印

world

hello

因为在处理事件之前(或甚至在处理事件)之前,调用线程可能会继续也可能不会继续.这取决于系统的线程调度程序.

同步

SwingUtilities.invokeAndWait(new Runnable() {

public void run() {

System.out.println("hello");

}

});

System.out.println("world");

这肯定会打印出来

hello

world

因为调用线程将在继续之前等待运行完成(除非抛出异常).

invokeAndWait使用等待和通知方案来实现此目的.创建一个monitor对象并将其提供给InvocationEvent.发布事件后invokeAndWait调用等待,并且在EDT上运行完成后InvocationEvent调用notifyAll.等待和通知方案是无法在EDT上调用invokeAndWait的原因. EDT没有办法在一个事件中间停止处理另一个事件.

如果多个事件排队会发生什么?

EDT按照它们排队的顺序并根据它们的优先级一次处理一个事件.某些事件也可以合并(常规的InvocationEvent不会).大多数事件都是正常的优先PaintEvent(类似于调用重绘)通常是低优先级的,并且某些系统事件具有更高的优先级.

在您给出的具体示例中:

SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

SwingUtilities.invokeLater(new Runnable() {

public void run() {

doSomethingElse();

}

});

由于它们是相同类型的事件和相同的优先级,因此doSomethingElse事件将在createAndShowGUI事件完成后处理.

同样,如果这样做了:

SwingUtilities.invokeLater(new Runnable() {

public void run() {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

System.out.println("world");

}

});

System.out.println("hello");

}

});

那将打印出来

hello

world

因为世界Runnable在hello Runnable完成后运行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值