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开发者_如何学Python 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.
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.
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.
精彩评论