BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

混淆了的工作单元和线程

| 作者 Niclas Nilsson 关注 0 他的粉丝 ,译者 孙向晖 关注 2 他的粉丝 发布于 2007年9月19日. 估计阅读时间: 4 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

许多服务器端的应用和许多桌面应用都含有与一个特殊任务的执行有关的数据。常见的解决方案是将这类数据放到线程本地存储区中,将变量中的数据与其执行线程相绑定。的确很方便,但这是一个基于有缺陷的假设的实践方案。

Bob Martin写了一篇关于假设线程跟工作单元存在一对一关系的专题文章:

ThreadLocal变量对一个给定的线程而言是一个极为便利的关联数据的方式。例如,类似于Hibernate这样的框架利用它来保存会话信息。但是,这种practice非常依赖于将一个线程和一个工作单元等同视之。这是一种错误的假设。

ThreadLocal是一个Java术语,但其构造在多线程环境中是通用的。Bob还记得:

十三年前写我的第一本书时,我和Jim Coplien针对线程和对象的本质发生了争论。他做出了一个令我如今仍记忆犹新的澄清,他说:“一个对象是功能的抽象,一个线程是调度的抽象”。

当前,将工作单元中的数据映射到一个线程中是一个标准的模式,一个在许多流行的框架中可以发现的模式,但即便是这种方法存在了相当长的时间,这个不完美的抽象仍然缺乏一些情景。

在一个任务的不同部分存在不同的优先级是很常见的事情,而且也没有规则约束说一个任务必须是单线程的。Bob举例说明一个工作单元在基于得到的数据执行一个相当长时间的计算时,可能会非常需要跟一个外部服务的响应性沟通,这样一个问题通常是分解成两个线程来解决。他问道:

工作单元相关的变量应该放在哪儿?它们不应被保存到ThreadLocal 中,因为任务的每一个部分在一个分离的线程中运行.它们也不能被保存在静态变量中,因为有很多的线程。最终答案是它们必须在线程间作为栈中的功能参数进行传递,并且被记录在存放于queue队列之中的数据结构内。

TapsaKoo不久前也遇到了一个同样的情况。当在WinForms中努力尝试领域驱动的方式时,他描述了他寻找一个保存会话专有数据的问题

如果应用程序每次只有一个表单被打开,我会把会话对象保存到Callcontext。如果应用每次打开多个表单,并且这些表单希望拥有我的session类的一个单独的实例时该怎么办?CallContext已经不能满足要求了。那么全都是线程专有的备选方案吗?还剩下什么了?什么也没有剩下?我已经不是考虑这个问题的第一个人了。可能会有存在一个解决方案,但我找不到它。我应该把会话对象注入达到需要它的每个对象实例中吗?还是我将领域类的许多行为重构到服务中,然后将会话对象注入其中?我不太喜欢这种方式,因为我希望我的类被数据容器有更多的含义。

在阅读完Bob大叔的回复后,TapsaKoo也同意对此问题没有轻松的解决方案

无论你有1个还是10个线程,问题总是相同的。工作单元或者会话状态应该存放在一个不依赖于线程的地方。认为工作单元直接对应于一个单个的线程是非常危险的假设。这种假设会严重限制你的其他的架构性选择。

Bob推断可能丢失了某些东西:

所以,尽管是司空见惯,ThreadLocal变量混淆了调度与功能的分离问题。它们诱惑我们将功能和调度耦合在了一起。这是非常不幸的事情,因为功能和调度的对应是脆弱的、偶然的。我们实际上应该做的是让建立一个UnitOfWorkLocal变量成为可能。
查看英文原文:Confusing unit-of-work with threads
译者简介:孙向晖,儿子小名“豆豆”,常被人称为“豆豆他爹”。1998年开始步入IT行业,现任浪潮软件质保中心副主任。专注于研究和实践MDA/UP/UML/SCM等相关技术在团队中的大规模应用,对产品化的软件项目管理、需求管理和配置管理略有心得。他的博客为http://blog.csdn.net/xiaosun/。参与InfoQ中文站内容建设,请邮件至china-editorial[at]infoq.com

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT