日期:2014-05-20  浏览次数:20762 次

AWT 组件是 “线程安全的(thread-safe)”,是什么意思?
网上有这种说法:AWT 组件是 “线程安全的(thread-safe)”,这意味着我们不需要关心在应用程序中是哪一个线程对 GUI 进行了更新。这个特性可以减少很多 GUI 更新的问题,不过使 AWT GUI 运行的速度更慢了。
AWT 组件是 “线程安全的(thread-safe)”,是什么意思,不需要使用java.awt.EventQueue.invokeLater()?那为什么设计上java.awt.EventQueue.invokeLater()?
------解决方案--------------------
是AWT被废弃的原因之一

AWT最初试图为用户保证: 用户”不需要关心在应用程序中是哪一个线程对 GUI 进行了更新“

后来证明这不现实
------解决方案--------------------
引用:
Quote: 引用:

是AWT被废弃的原因之一

AWT最初试图为用户保证: 用户”不需要关心在应用程序中是哪一个线程对 GUI 进行了更新“

后来证明这不现实
你的意思是,使用java.awt.EventQueue.invokeLater()才能确保?不使用则不一定?


我没有用过awt,所以我不知道。

我知道awt最初是想让用户可以在任何线程调用ui更新,后来经常出现死锁,再后来我就不知道了,再后来Swing出现了,吸取了awt的教训,采用了单线程事件队列的设计。
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

是AWT被废弃的原因之一

AWT最初试图为用户保证: 用户”不需要关心在应用程序中是哪一个线程对 GUI 进行了更新“

后来证明这不现实
你的意思是,使用java.awt.EventQueue.invokeLater()才能确保?不使用则不一定?


我没有用过awt,所以我不知道。

我知道awt最初是想让用户可以在任何线程调用ui更新,后来经常出现死锁,再后来我就不知道了,再后来Swing出现了,吸取了awt的教训,采用了单线程事件队列的设计。
Oracle不是写了关于GUI用多线程不现实的专业文章的吗,你可以去看看
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

是AWT被废弃的原因之一

AWT最初试图为用户保证: 用户”不需要关心在应用程序中是哪一个线程对 GUI 进行了更新“

后来证明这不现实
你的意思是,使用java.awt.EventQueue.invokeLater()才能确保?不使用则不一定?


我没有用过awt,所以我不知道。

我知道awt最初是想让用户可以在任何线程调用ui更新,后来经常出现死锁,再后来我就不知道了,再后来Swing出现了,吸取了awt的教训,采用了单线程事件队列的设计。
Oracle不是写了关于GUI用多线程不现实的专业文章的吗,你可以去看看
我可以发文件给你邮箱
------解决方案--------------------
举个例子,假设不是线程安全的,有两个线程在绘制一个图片到屏幕上,那就可能会出现,左边是图片1,右边是图片2.而实际你要的可能是1在上面或者2在上面。

意思也就是说,你的所有UI事件,包括绘制、鼠标触发、组件大小变化……这些都不会是在多个线程内触发的。
其实,最简单的说,把所有提供给外部的方法调用(比如repaint)内部都封装成一个事件,然后放到队列里面顺序执行。这样不管你是多少个线程调用了repaint。他始终在事件队列中,而有个专门处理这个事件队列的线程,就会把队列的请求一个个拿出来处理。

------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

是AWT被废弃的原因之一

AWT最初试图为用户保证: 用户”不需要关心在应用程序中是哪一个线程对 GUI 进行了更新“

后来证明这不现实
你的意思是,使用java.awt.EventQueue.invokeLater()才能确保?不使用则不一定?


我没有用过awt,所以我不知道。

我知道awt最初是想让用户可以在任何线程调用ui更新,后来经常出现死锁,再后来我就不知道了,再后来Swing出现了,吸取了awt的教训,采用了单线程事件队列的设计。
Oracle不是写了关于GUI用多线程不现实的专业文章的吗,你可以去看看
我可以发文件给你邮箱


raistlic@gmail.com

谢谢 =)
------解决方案--------------------
引用:
Oracle不是写了关于GUI用多线程不现实的专业文章的吗,你可以去看看


其实以前也看过一篇,
文中大体意思说,
出现无法避免的死锁是因为从两个相反方向来的调用(从操作系统来的和从用户来的)总会试图以相反的顺序获取多个锁。

要完全避免这种问题,——所有相关数据使用同一把锁,事实上(对这些相关数据的访问来说)等同于单线程拘禁,——单线程事件队列的设计就成了顺理成章的事。

为什么选择【单线程拘禁】而不是【使用同一把锁】,我的理解是对相关数据来说,多个线程【使用同一把锁】多了线程间数据同步的开销,而【单线程拘禁】不存在这个开销。

我觉得单线程队列的模式其实可以做成 java.util.concurrency 中的工具类的,比如定义其lifecycle的接口,使用特定的ThreadFactory,提供类似 invokeLater(Runnable), boolean isTaskQueueThread() 这样的服务,用对象的方式而不是静态方法的方式实现一个单线程runnable队列,同时可以用类似 invokeAndWait 的方法支持传入 Callable<E> 返回一个 E 类型的结果………… 有很多可以做,做成方便的工具。

——其实我自己做了一个,合适的时候准备发到blog :)