我想知道哪一种更好的方法以线程安全的方式加载数据.传统上,我使用了双锁模式,这很好地达到了目的.现在,通过添加System.Lazy类型,我想知道是否依赖于Lazy和Loading的内部更好并且以更好的方式完成工作.它看起来更干净,更容易阅读,但它更好吗?
有什么想法吗?
namespace SomeNameSpace
{
public class DataStoreContext
{
private readonly static Lazy<DataStoreContext> context = new Lazy<DataStoreContext>(() => new DataStoreContext());
private Lazy<Dictionary<string, Entity>> _entities = new Lazy<Dictionary<string, Entity>>(() => { return DataStoreContext.Instance.Load(); });
private readonly object _syncRoot = new object();
private DataStoreContext()
{
}
public Dictionary<string, Entity> Data
{
get { return _entities.Value; }
}
public static DataStoreContext Instance
{
get { return context.Value; }
}
private Dictionary<string, Entity> Load()
{
// Load Data from some data store.
return null;
}
private Dictionary<string, Entity> LoadWithLock()
{
if (_entities == null)
{
lock (_syncRoot)
{
if (_entities == null)
{
Dictionary<string, Entity> entities = this.Load();
_entities = entities;
return _entities;
}
}
}
return _entities ;
}
public void Clear()
{
_entities = new Lazy<Dictionary<string, Entity>>(() => { return DataStoreContext.Instance.Load(); });
}
}
}
Run Code Online (Sandbox Code Playgroud)
它看起来更干净,更容易阅读,但它更好吗?
是.双重检查锁定很难正确.它需要内存屏障才能正确.CIL*实际上并未保证您的实施安全.
有关详细信息,请参阅此Wikipedia条目.
通过使用Lazy<T>,您获得的代码不仅更清晰,而且在所有平台上实际上都是正确的.
*请注意,由于平台的内存模型,这可能在运行Microsoft运行时的x86和x64上完美运行.但是,如果没有适当的内存屏障,则不能保证规格是正确的.
根据 MSDN 的文档:
默认情况下,Lazy 类的所有公共和受保护成员都是线程安全的,并且可以从多个线程并发使用。使用类型构造函数的参数,可以根据实例选择性地删除这些线程安全保证。
对于读和写操作来说,它都是线程安全的。因此,我会说坚持这个,因为它更干净。
但是,正如文档所述,您可以使用构造函数的一些可选参数来关闭线程安全性。
| 归档时间: |
|
| 查看次数: |
418 次 |
| 最近记录: |