这种并发模式有名字吗?
问题是:我们有永远不应该阻塞的关键路径代码。在许多地方,它依赖于来自外部源的配置数据或类似的、不经常更新的数据。
当我们需要重新加载配置数据或从外部源刷新数据时,我们不希望锁定对该数据的访问并可能阻塞关键路径线程。
解决方案:将有问题的数据移动到它自己的类中。使用后台线程完全执行重新加载并验证数据。然后,准备就绪后,用新数据引用覆盖旧数据引用。
该引用必须是易失性的,以确保所有线程的可见性。
只要关键路径代码不总是具有最新的可用数据,这种方法就可以很好地工作,并且对性能的影响绝对最小(所有数据都经过易失性引用)。
真正的问题是,这种并发设计模式有名字吗?
所讨论的语言是 Java,但我认为这适用于大多数支持共享内存并发编程风格的语言。
The problem: we have critical path code that should never block. In many places it relies on configuration data, or similar, infrequently updated data from an external source.
When we need to reload configuration data, or refresh data from an external source, we don't want to lock access to that data and potentially block the critical path threads.
The solution: move the data in question to its own class. Use a background thread to fully perform the reload and validate the data. Then, when its ready, overwrite the old data reference with the new one.
This reference must be volatile to ensure visibility to all threads.
As long as its not imperative that the critical path code always have the most recent data available, this works great, with the absolute minimum performance impact (all data goes through a volatile ref).
The real question is, is there a name for this concurrency design pattern?
The language in question is Java, but I think this applies to most that support a shared-memory concurrency style of programming.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对我来说,对值对象的原子引用看起来像是
一个持久对象。它仅代表一个值,即它代表从调用构造函数那一刻到其生命周期结束的值(无状态更改)。作为一个值对象,它自动是线程安全的。
对它的原子引用只是访问值对象最新版本的中心点。
Clojure 语言将其称为“ref”。
我找到了一篇关于 GoF 形式的设计模式的博客文章,看起来像你想要的:
http://tobega.blogspot.com/2008 /03/java-thread-safe-state-design-pattern.html
编辑:
Rich Hickey(Clojure 的创建者)将其定义为 Identity:“我们关联的假定实体随着时间的推移,具有一系列因果相关的值(状态)”。
来源:http://www.infoq.com/presentations/Are -我们还有富人希基
For me, it looks like a atomic reference to a Value Object
Value Object is a persistent object. It just represents a value, i.e. it represent a value from the moment you call the constructor to the end of it's life (no state change). Being a Value Object it is automatically Thread-safe.
The atomic reference to it is just a central point to get access to the last version of the Value Object.
The Clojure language call it a "ref".
I've found a blog post about a design pattern, in GoF form, that looks like what you want:
http://tobega.blogspot.com/2008/03/java-thread-safe-state-design-pattern.html
EDIT:
Rich Hickey (creator of Clojure) define it as Identity: "A putative entity we associate with a series of causally related values (states) over time".
Source: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
双缓冲可能是您正在寻找的术语吗?
Could double buffering be the term you're looking for?
您仍然可以进行高性能锁定。这听起来很危险。不管怎样,您需要在锁定时获取数据的副本,然后解锁它,然后处理该数据。
You can still do high-performance locking. This just sounds dangerous. Anyway, you'll want to take a copy of the data -- while locked -- unlock it, then work on that data.
我的结论是这种模式没有众所周知的名称。
clojure 中的概念清晰地映射到我在此处描述的内容,但是 Ref 和 Identity 对于 Java 中的设计模式名称的描述性不够。感谢@Thiago 指出了这些。
还要感谢 @Ed 指出双缓冲图形和硬件是一个非常相似的概念,但同样它不能作为 Java 中的设计模式名称。
出于我的目的,我将与同事一起使用类似于原子构建和交换的东西,以便我们可以处理这种频繁出现的设计。
I'm going to conclude that there is no well-known name for this pattern.
The concepts from clojure map cleanly to what I've described here, but Ref and Identity aren't sufficiently descriptive for a design pattern name in Java. Thanks to @Thiago for pointing these out though.
Thanks also to @Ed for pointing out that double buffering graphics and hardware is a very similar concept, but again it doesn't work as a design pattern name in Java.
For my purposes, I'm going to use something along the lines of Atomic Build and Swap with coworkers so that we can have a handle for this frequently occurring design.