internal abstract class BaseManager<I> where I: IEntityProvider { private static I _provider = default(I); private static object _syncLock = new object();protected static I Provider { if (_provider == null) { lock (_syncLock) { if (provder = null) provider = Activator.createfromconfig(...); } } return _provider; }
The double-check locking pattern is a low-lock solution to a multithreading problem, and it is therefore: a - tempting, because efficient, b - controversial, because complicated. It is controversial, because it is very hard to say whether it will be thread-safe on all processor architectures and all jitters with the .NET memory model. It requires detailed knowledge of the memory model (which is different between the .NET 1.1 ECMA specification, the .NET 1.1 x86 MS implementation, and the .NET 2.0 specification/implementations), and even then experts argue both ways. I believe this is why Jon Skeet discourages from using it. In particular, it is currently not exactly clear to me whether your implementation will be safe on all platforms or not, because your _provider member is not marked as volatile. Note that the MSDN patterns and practices article linked previously [1] suggests to use the volatile keyword. It's from 2002, however, so it's based on one of the 1.1 memory models. There is a second article (without date, but it is more recent), which also suggests using volatile [2]. I have also read some blog entries by Joe Duffy (e.g. [3]) where he states he believes that some _variants_ of the double-checked locking patterns are broken (e.g. if you use a boolean flag to indicate whether the variable was initialized or not). Also, solutions using double-checked locking are so incredibly hard to test, because if you get something wrong, it will usually not show on x86 with the current JIT compiler. It will only show on other architectures (e.g. IA64) or with other JIT compilers. And even on such platforms, it will only show occasionally, without being reproduceable. Bottom line: Lock-free (or low-lock) multithreading is so complicated that I believe you should typically use another alternative. The performance gain is minimal. If you have a situation where you absolutely need it, use volatile or get really, really involved with the topic to learn whether you can leave it out. Fabian [1] http://msdn2.microsoft.com/en-us/library/ms954629.aspx [2] http://msdn2.microsoft.com/en-us/library/ms998558.aspx [3] http://www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx =================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com
