作者sbrhsieh (十年一梦)
看板java
标题Re: [问题] EventQueue.invokeLater 使用疑问
时间Wed Apr 29 22:00:11 2015
※ 引述《noapaov (单身汉)》之铭言:
: 标题: [问题] EventQueue.invokeLater 使用疑问
: 时间: Wed Apr 29 11:59:43 2015
:
:
: 请教一下各位, 目前在Swing碰到一个疑问,
:
: 看了大多数的书籍, 在使用Swing建议使用方法如下
: public static void main(String args[]) {
:
: java.awt.EventQueue.invokeLater(new Runnable() {
: public void run() {
:
: System.out.println("test");
: new NewJFrame().setVisible(true);
: }
: });
: }
:
: 也就是视窗程式会开一个thread来处理Event Queue和GUI的事情,
:
: 但我是用下列方法一样会产生该视窗物件, 也没发生什麽错误
:
: public static void main(String args[]) {
: new NewJFrame().setVisible(true);
:
: }
:
: 想请问各位大大, 这两着到底差别在哪? 谢谢
:
: --
:
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 203.69.59.91
: ※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1430279986.A.363.html
: 推 mars90226: 把GUI跟处理程式主要功能的thread分开,这样你就不会 04/29 12:04
: → mars90226: 在处理事情的时候,GUI看起来像是没有回应 04/29 12:05
: → mars90226: 你如果没做甚麽花很多时间的事情,就会没甚麽差别 04/29 12:05
推文讲的观念本身是正确的,是每个搞 GUI 的人都需要知道的事,但是此帖主要
是关於为什麽需要把 UI component 的建立与操作放到 UI thread 里*,推文回覆
的就不是那麽贴切。
swing 的文件里有提到 swing 设计上除了少数几个特定的 methods 外(repaint,
setText...),大部分都不是 thread-safe,也就是说同时**在多个 thread 里各自
对同一 swing component 进行操作,不保证能维持 component(object) 的
invariant 性质(component 不一定会处在一个合理的状态)。
就理论上来说,不知道 swing component 的 constructor 确切做了什麽事(有没有
把自身的 reference 扩散到 UI thread 里,有没有操作(或被操作)其他的 swing
component 了等等),保险的做法是从建构 swing component 这一动作开始就排程到
UI thread 去做,就能确保所有的 swing component 会处在一种正确合理的状态。
至於直接在 main thread 执行这样的操作,你说也没有错误:
new NewJFrame().setVisible(true);
比较保守的看法是:
1. 某些 swing component 已经烂掉了,但是你还没有(或没办法)观察到。
2. 你运气好,当次执行这个程式後,确实是没有任何 swing component 烂掉。
比较大胆的看法是:
在你使用的 JRE 所带的 core classes implementation 之下,在 main thread
里做这些操作本来就(刚好)总是不会有问题的。
有人争论过到底可不可(安全地)在 main thread 里建构 main frame(window) 以及
初始化的操作,这部分我不想评论。
*直到 Java 8(1.8) 的 API doc,EventQueue.invokeLater/invokeAndWait 部分都
没有明讲是把 Runnable 排到 UI thread 里去执行,但是 SwingUtilities 里同名
的两个 method 则有明确提到是把 Runnable 排到 UI thread(event dispatching
thread)里去执行,且 SwingUtilities 的实作只是 cover for
java.awt.EventQueue.invokeLater()/java.awt.EventQueue.invokeAndWait()。
**这里的"同时"意指在某个 thread A invoke component C 的 methodA 到
methodA return 的这段时间,与某个 thread B invoke 同一 Component C 的
methodB 到 methodB return 的这段时间,两者有重叠的部分。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.238.70.213
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1430316014.A.1CB.html
※ 编辑: sbrhsieh (36.238.70.213), 04/29/2015 22:05:51