为什么说GUI是单线程化的

刚好最近实现了一版事件模型,GUI 的逻辑处理几乎都由事件驱动,我认为比较重要的原因有:
事件模型就是典型的"职责链模式"(Chain-of-responsibility pattern),看看职责链的优势就知道了:可动态增加减少接收者,可动态调整接收优先级
每个接收对象都有机会响应事件,每个事件可由多个对象同时处理
对于处理不了的事件,接收对象可以不做处理,减少外部耦合
对于已经处理的事件,接收对象可以选择停止派发,也可以选择继续派发
事件模型还充分应用了"监听器模式":解耦事件发送者和接收者
每个事件可触发多种逻辑
还有很重要一点:单线程的应用如果想处理外部事件,都离不开消息循环,而事件模型和消息循环是天生一对。桌面上,最广为人知的消息循环恐怕就是Windows了,WinMain 方法都是一个死循环,不断的读取并处理Windows消息,大家都玩过你懂的。(派发给窗体)
网页上,JavaScript 应用也是单线程的,靠浏览器的消息循环驱动各种事件和回调。(派发给DOM)



作者:Jare Guo
链接:http://www.zhihu.com/question/26805116/answer/34124946
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



 现代的gui框架使用了一个略微不同的模型:模型创建了一个专门的线程,事件派发线程(event dispatch thread,RDT)来处理gui事件。单线程化的GUI框架并不仅仅存在于java中:Qt、NextStep、Macos Cocoa、XWindows,等等都是单线程化的。也并不缺少反面的尝试;有很多试图写出多线程的GUI框架的努力,最终都由于竞争条件和死锁导致的稳定性问题,又回到了单线程化的事件队列模型的老路上来:采用一个专门的线程从队列中抽取事件,并把它们转发给应用程序定义的事件处理器。(awt最初曾尝试在某种程度上支持多线程访问,单线程化地实现swing的决定主要基于AWT中的经验和教训。)多线程的GUI框架会尤其易受死锁的影响,部分原因在于,输入事件处理与任何GUI组件背后的对象模型之间存在偶发的交互。用户发起的动作总会冒泡似的从操作系统传递给应用程序—先是由os检测到一次鼠标点击,然后工具集把它转化为“鼠标点击”事件,最终它会作为一个高层事件(比如“buttonpressed”事件)转发给应用程序的监听器。另一方面,应用程序发起的动作又会以冒泡的形式传回操作系统—应用程序发起一个动作要改变某个组件的背景颜色,这会被转发给一个特定的组件类,最终转发给os进行渲染。两种动作以完全相反的顺序访问相同的GUI对象,需要保证让每一个对象都是线程安全的,这会导致一系列的锁顺序的不一致,这会直接引发死锁。这个问题机会在每一次GUI工具集的开发中都会出现,是经验之谈。模型—视图—控制器(mvc)模式的普遍流行形成了导致多线程GUI框架出现死锁的另一原因。把用户的互交分拨到模型、视图和控制器之间的写作中,极大地简化了GUI应用程序的实现,但这让不一致的锁顺序再次雪上加霜。控制器调用模型,模型通知视图已经发生了一些事情。控制器同样可以调用视图,视图可以依次回调模型来查询模型的状态。结果是,不一致的锁顺序再次伴随死锁的风险一同到来。Graham hamilton,sun公司的vp,在他的weblog中详尽地概括了这些挑战,描述了多线程GUI工具集之所以会成为计算机科学史上又一次“失败的梦”。如果多线程GUI工具集经过非常谨慎的设计;如果工具集能使它加锁的方法鲜明地显露;如果你非常聪明,非常仔细,并且对工具集的整体框架有着全局的把握,我相信你还是可以成功地编写出多线程的GUI来。但是如果这些事情有一些轻微的偏差,程序多数时候仍然运行良好,但是你会偶尔看到程序挂起或者运行故障。那些密切参与了工具集设计的人能够很好地运用这种多线程方案。不幸的是,我认为这些特性并没有和商业流行度成正比。一个中等能力的程序员,整日构建着被一些莫名其妙的原因困扰着而不能稳定运行的应用程序,我们很容易落入这种境界。于是应该程序的作者会倍感怨恨与失落,对无辜的工具集恶语相加。单线程化的GUI框架通过现场限制来达到现场安全性;所有GUI中的对象,包括可视组件和数据模型,都只是被事件线程访问。当然,这只把线程安全负担的一部分推给了应用程序的开发者,他们必须确保这些对象是被正确限制的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java聊天室GUI是一种基于Java编程语言的图形用户界面,用于创建聊天室应用程序。可以使用Java的GUI库,如Swing或JavaFX来实现聊天室的图形界面。通常,聊天室GUI会包含以下功能: 1. 用户登录和注册:提供用户名和密码输入框,以便用户可以登录或注册一个新账号。 2. 在线列表:显示当前在线的用户列表,以便用户可以选择要与之聊天的用户。 3. 公共聊天室:提供一个公共聊天室,允许用户在其中发送和接收消息。这些消息将被广播到所有在线用户。 4. 私人聊天:允许用户选择其他在线用户进行私人聊天。私人聊天可能需要创建一个单独的聊天窗口或对话框。 5. 发送文字和文件:允许用户发送文字消息和文件附件给其他用户。 6. 聊天记录:保存聊天消息的历史记录,并允许用户查看和搜索以前的消息。 7. 下线:提供选项让用户退出聊天室,并关闭应用程序。 根据引用和引用,我们可以使用多线程来实现聊天室GUI。主线程负责用户界面的呈现和用户输入的处理,而子线程则负责接收其他用户发送的消息并在GUI上显示。可以使用Socket来建立与服务器的连接,并使用输入流和输出流来发送和接收消息。 在GUI设计中,可以使用窗口、标签、文本框、按钮等组件来构建聊天室界面。例如,可以使用文本框来显示聊天记录,输入框来输入消息,按钮来发送消息,列表框来显示在线用户等。需要注意的是,通过适当的布局管理器来布置组件,使界面看起来更加美观和用户友好。 根据引用,还可以在服务器端使用特定的对象来存储用户信息和聊天记录。可以使用ServerSocket类来接收客户端连接,并使用线程池等方式来管理多个客户端的并发连接。 总而言之,Java聊天室GUI是一种使用Java编程语言和GUI库来创建具有图形界面的聊天室应用程序。它可以提供用户登录和注册、在线列表、公共聊天室、私人聊天、发送文字和文件、消息记录和下线等功能。使用多线程和Socket编程可以实现与服务器的通信和消息的传递。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【Java GUI】用Java实现简单聊天室的制作 项目(二)](https://blog.csdn.net/m0_72091619/article/details/131342788)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Java聊天室项目GUI界面实现(Java聊天室 IO流 Socket流 GUI界面 )](https://blog.csdn.net/cx9977/article/details/108484313)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值