c#使用延迟初始化和锁在一起

本文关键字:在一起 初始化 延迟 | 更新日期: 2023-09-27 18:18:34

我希望我的一些对象延迟初始化,如:

private static Lazy<MappingEngine> engine = new Lazy<MappingEngine>(() =>
{
    return new MappingEngine();
})

并且我不希望在初始化之后有多个线程访问这个对象。我是否也应该使用锁机制来防止这种情况,或者Lazy是否以这种方式支持线程安全?同时使用Lazy和lock似乎不是正确的方法。

在文档中声明"使Lazy对象线程安全并不能保护惰性初始化的对象。如果多个线程可以访问延迟初始化的对象,则必须使其属性和方法对多线程访问是安全的。"

是写一个自定义类型,这是一个懒惰的类型,它把锁每次engine.Value被称为一个逻辑的事情吗?举个例子:

public class MyLazyType<T> : Lazy<T>
{
    private object lockObj = new object(); //not static since the reference to this class will be
    public MyLazyType(Func<T> valueFactory) : base(valueFactory)
    {
    }
    public new T Value
    {
        get
        {
            lock (lockObj)
            {
                return base.Value;
            }
        }
    }
}

用法:

private static MyLazyType<MappingEngine> engine = new MyLazyType<MappingEngine>(() =>
{
    return new MappingEngine();
})

c#使用延迟初始化和锁在一起

您对Lazy<T>的专门化没有提供额外的好处。被强调的问题如下:

var t1 = new Thread(()=>{
    myLazy.Value.SomeNonThreadsafeMethod();
});
var t2 = new Thread(()=>{
    myLazy.Value.SomeNonThreadsafeMethod();
});
t1.Start();
t2.Start();
显然,在您获得值之后,lazy在其操作中不再起作用,如果要跨多个线程使用该值,则需要在其方法和属性中编写额外的保护。