【发布时间】:2011-05-15 20:35:21
【问题描述】:
考虑以下代码:
public class Foo
{
private static object _lock = new object();
public void NameDoesNotMatter()
{
if( SomeDataDoesNotExist() )
{
lock(_lock)
{
if( SomeDataDoesNotExist() )
{
CreateSomeData();
}
else
{
// someone else also noticed the lack of data. We
// both contended for the lock. The other guy won
// and created the data, so we no longer need to.
// But once he got out of the lock, we got in.
// There's nothing left to do.
}
}
}
}
private bool SomeDataDoesNotExist()
{
// Note - this method must be thread-safe.
throw new NotImplementedException();
}
private bool CreateSomeData()
{
// Note - This shouldn't need to be thread-safe
throw new NotImplementedException();
}
}
首先,我需要说明一些假设:
有一个很好的理由,我不能只在应用启动后执行此操作。也许数据还不可用,等等。
Foo 可以从两个或多个线程同时实例化和使用。我希望其中一个最终创建一些数据(但不是两个),然后我将允许两者访问相同的数据(忽略访问数据的线程安全)
SomeDataDoesNotExist() 的开销并不大。
现在,这不一定限于某些数据创建情况,但这是我能想到的一个例子。
我对识别为模式特别感兴趣的部分是检查 -> 锁定 -> 检查。有几次,我不得不向那些乍一看并没有理解算法但后来理解它的开发人员解释这种模式。
无论如何,其他人也必须这样做。这是标准化的模式吗?它叫什么?
【问题讨论】:
-
对我来说,使用同步 lazy-loaded、singleton pattern 似乎是一种奇怪的方式。
-
您的意思是可能有更好但功能等效的方法来执行此操作。你具体是怎么想的?
-
我说的很奇怪,因为它将多种模式组合成一种方法。通常我希望以不同的方法看到它们。即,延迟加载的单例(数据)将位于单独的方法/属性中。
-
第 2 点有问题。访问数据时需要某种“线程安全”。没有它,您无法确保在访问数据之前已完全创建数据。
-
我同意,伊什塔尔。我只是想从概念上分离这个问题。但是您绝对是对的,检测数据似乎存在但不完整的场景很重要。
标签: c# java design-patterns