3

使用非静态字段的双重检查锁定是否正确?

class Foo
{ 
   private SomeType member;
   private readonly object memeberSync = new object();
   public SomeType Memeber
   { 
      get
      {
         if(member == null)
         { 
            lock(memeberSync)
            {
               if(member == null)
               {
                  member = new SomeType();
               } 
            }
         }
         return object;
      }
   }
}
4

3 回答 3

6

使用非静态字段的双重检查锁定是否正确?

是的,您的代码使用双重检查lock来获得线程安全延迟加载没有任何问题。如果您从 .NET 4 开始使用,建议使用Lazy类,这种方法与线程安全延迟加载的结果相同,但它也使您的代码更简单、更具可读性。

class Foo
{
    private readonly Lazy<SomeType> _member = 
                                   new Lazy<SomeType>(() => new SomeType());

    public SomeType Member
    {
        get { return _member.Value; }
    }
}
于 2012-10-24T08:34:17.467 回答
2

外部检查可以提高性能,因为一旦member初始化,您不必每次访问属性时都获取锁。如果您经常从多个线程访问该属性,则锁的性能影响可能非常明显。

内部检查对于防止竞争条件是必要的:没有它,两个线程可能会处理外部if语句,然后两个线程都会初始化member

严格来说,外部if不是必需的,但它被认为是一种很好的做法,并且(在重线程应用程序中)性能优势会很明显。

于 2012-10-24T08:32:57.620 回答
0

这是一些人推荐的做法,因为在释放另一个锁之前,您的锁可能不会应用。

在这种情况下,两个线程同时访问 getter,第一个获得锁,第二个等待。

一旦第一个线程完成,第二个线程现在就有了锁。

在可能的情况下,您应该检查变量是否在当前线程获得锁之前已由另一个线程创建。

于 2012-10-24T08:30:31.450 回答